Android Packet Filter

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

Ringkasan APF

APF terdiri dari dua komponen utama:

  • Interpreter APF berjalan di hardware jaringan (biasanya, chipset Wi-Fi). Interpreter 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 Network Stack dapat memperbarui 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 (RA) IPv6, memfilter traffic multicast dan broadcast jika kunci multicast tidak dipegang, 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 membuat aturan untuk membalas jenis paket umum yang biasanya memerlukan CPU untuk aktif agar dapat merespons, seperti kueri ARP dan kueri NS. Daftar lengkap filter ditentukan dalam ApfFilter.

Karena kode pembuatan program APF adalah bagian dari modul Network Stack, Anda dapat menggunakan [update Mainline 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 interpreter APF dan hardware ditentukan dalam apf_interpreter.h (APFv4, APFv6). Kode firmware Wi-Fi memanggil accept_packet() di APFv4 atau apf_run() di APFv6 untuk menentukan apakah paket harus di-drop (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 prosesor aplikasi. Jika firmware mendukung APFv6, firmware harus menerapkan API apf_allocate_buffer() dan apf_transmit_buffer(). Interpreter APF memanggil kedua API ini selama logika transmisi paket. Petunjuk APF memiliki panjang yang bervariasi. Setiap instruksi memiliki panjang minimal 1 byte. Kode instruksi 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 APF HAL. Bytecode APF menggunakan penyimpanan data untuk menyimpan penghitung paket yang diterima dan di-drop. Wilayah data dapat dibaca dari framework Android. Petunjuk APF efisien dalam penggunaan memori, tetapi untuk memaksimalkan potensi penghematan daya dan fungsionalitasnya, diperlukan aturan pemfilteran dinamis yang kompleks. Kompleksitas ini memerlukan bagian memori khusus pada chipset. Persyaratan memori minimum untuk APFv4 adalah 1024 byte, sedangkan APFv6 memerlukan 2048 byte. Namun, sebaiknya alokasikan 4.096 byte untuk APFv6 guna memastikan performa yang optimal. Interpreter APF harus dikompilasi ke dalam firmware. Interpreter APFv4 dan APFv6 dioptimalkan untuk ukuran kode. Dalam arsitektur arm32, interpreter APFv4 yang dikompilasi berukuran sekitar 1,8 KB, sedangkan interpreter 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 mereka 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 akses filter APF ke seluruh paket, bukan hanya header, saat APF diaktifkan.

Contoh program APF

ApfTest dan ApfFilterTest berisi program pengujian sampel yang menggambarkan cara kerja setiap filter APF. Untuk mempelajari program yang dihasilkan sebenarnya, 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 membuat program pelepasan APFv6. Untuk mengetahui detail selengkapnya, lihat dokumentasi di file utilitas Python.

Men-debug APF

Untuk memeriksa apakah APF diaktifkan di perangkat, tampilkan program saat ini, tunjukkan 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 program biner APF yang diinstal terbaru dalam format string hex.
  • APF packet counters: Bagian ini menunjukkan jumlah paket yang diteruskan atau dihapus oleh APF dan alasan spesifiknya.

Untuk mendekode dan membongkar kode menjadi 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 interpreter APFv4 dan APFv6.

Berikut adalah panduan untuk perintah apf_run. Secara default, perintah apf_run dijalankan di interpreter APFv4. Meneruskan argumen --v6 ke apf_run memungkinkannya berjalan terhadap interpreter 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 dilepas atau diteruskan.

Untuk memberikan representasi 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 berukuran 4 byte, region data harus cukup panjang untuk memastikan tidak terjadi buffer overflow.

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 interpreter, yang berguna untuk men-debug. Dalam contoh ini, kita memasukkan paket kueri ARP ke dalam program APF. Output menunjukkan bahwa kueri ARP dihentikan, tetapi paket balasan dibuat. Detail paket yang dihasilkan ini ditampilkan di bagian transmitted packet.

Masalah integrasi umum

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

  • Pembersihan wilayah data yang tidak terduga: Memori APF harus sepenuhnya dikhususkan untuk APF; hanya kode interpreter atau kode framework (melalui HAL API) yang diizinkan untuk mengubah wilayah memori APF.
  • Masalah penginstalan dengan program APF sebesar X byte (X <= maxLen): Firmware harus mendukung pembacaan atau penulisan panjang program apa pun hingga maxLen tanpa kegagalan, error, atau pemotongan. Penulisan tidak boleh mengubah byte apa pun antara X dan maxLen.
  • Penerapan APF dalam kode driver: APF hanya boleh diterapkan dalam firmware, bukan kode driver. Jika tidak, tidak ada manfaat penghematan daya karena CPU harus 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 tentang cara menghitung 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 aktif atau traffic di bawah 10 Mbps.
  • Paket yang terpotong 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 interpreter APF guna memastikan fungsi APF yang benar. Berikut perincian tujuan setiap kasus pengujian:

  • ApfFilter dan apf_interpreter pengujian integrasi: Memverifikasi bahwa ApfFilter menghasilkan bytecode yang benar, dan apf_interpreter mengeksekusi 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 diaktifkan saat layar nonaktif dan traffic Wi-Fi di bawah 10 Mbps.
    • Kemampuan APF dinyatakan dengan benar.
    • Operasi baca dan tulis pada region memori APF berhasil, dan region memori tidak dimodifikasi secara tidak terduga.
    • Argumen diteruskan dengan benar ke accept_packet() atau apf_run().
    • Firmware yang terintegrasi dengan APFv4/APFv6 dapat menghilangkan 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 dibuat di sisi pengirim, dan pengujian mengonfirmasi apakah paket tersebut ditolak, diteruskan, atau dibalas dengan benar berdasarkan aturan yang dikonfigurasi di ApfFilter.

Petunjuk pengujian integrasi tambahan

Selain itu, sebaiknya vendor chipset menyertakan 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 make-before-break atau roaming. 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. Programnya dalam format 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 memicu logika pemfilteran di program 1 dan program 2.

Program APF 1

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

Logika program APF 1 adalah sebagai berikut:

  1. Menjatuhkan dan menambah penghitung:
    1. Nilai EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Paket penemuan atau permintaan DHCP IPv4
    3. Paket RS
  2. Teruskan dan naikkan penghitung: Semua paket lainnya.

Kode 1 byte program APF adalah sebagai berikut:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Program APF 2

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

Logika program APF 2 adalah sebagai berikut:

  1. Menjatuhkan dan menambah penghitung:
    1. Nilai EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Paket penemuan atau permintaan DHCP IPv4
    3. Paket RS
  2. Menjatuhkan dan menambahkan penghitung: Paket permintaan ping ICMP
  3. Teruskan dan naikkan 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 dihentikan dengan benar, lakukan hal berikut:

  • Mengambil dan memverifikasi region data APF setiap 5 menit.
  • Jangan hapus 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]

Kode semu 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