ตัวกรองแพ็กเก็ต Android (APF) ช่วยให้เฟรมเวิร์กควบคุมตรรกะการกรองแพ็กเก็ตฮาร์ดแวร์ขณะรันไทม์ได้ ซึ่งช่วยให้ระบบประหยัดพลังงานได้ด้วยการทิ้งแพ็กเก็ตในฮาร์ดแวร์ ขณะเดียวกันก็อนุญาตให้เฟรมเวิร์ก Android เปลี่ยนกฎการกรองขณะรันไทม์ตามสภาพเครือข่ายได้
ภาพรวมของ APF
APF ประกอบด้วยองค์ประกอบหลัก 2 ส่วน ได้แก่
- ตัวตีความ APF ทำงานบนฮาร์ดแวร์เครือข่าย (โดยปกติคือชิปเซ็ต Wi-Fi) ตัวตีความ APF จะเรียกใช้ไบต์โค้ด APF ในแพ็กเก็ตที่ฮาร์ดแวร์ได้รับ และตัดสินใจว่าจะยอมรับ ทิ้ง หรือตอบกลับแพ็กเก็ตเหล่านั้น
- โค้ดการสร้างโปรแกรม APF ทำงานบน CPU หลัก โค้ดจะสร้างและอัปเดตโปรแกรม APF ตามสถานะเครือข่ายและอุปกรณ์
เมธอด Wi-Fi HAL ช่วยให้เฟรมเวิร์ก Android ติดตั้งไบต์โค้ดโปรแกรม APF และอ่านตัวนับปัจจุบันได้ โมดูล Network Stack Mainline สามารถอัปเดตไบต์โค้ดโปรแกรม APF ได้ทุก เมื่อขณะที่ APF ทำงานอยู่
มีการติดตั้งใช้งานตัวกรอง APF หลายรายการ เช่น APF มีตัวกรองเพื่อทิ้ง EtherType ที่ไม่อนุญาต กรองแพ็กเก็ตการโฆษณาเราเตอร์ (RA) ของ IPv6 กรองการรับส่งข้อมูลแบบมัลติแคสต์และบรอดแคสต์หากไม่ได้ล็อกมัลติคาสต์ ทิ้งแพ็กเก็ต DHCP สำหรับโฮสต์อื่นๆ และทิ้งแพ็กเก็ต Address Resolution Protocol (ARP) และการค้นพบเพื่อนบ้าน (ND) ที่ไม่พึงประสงค์ หากเฟิร์มแวร์รองรับ APFv6,
ApfFilter จะสร้างกฎเพื่อตอบกลับแพ็กเก็ตประเภททั่วไปที่ปกติแล้วจะต้องให้ CPU ตื่นขึ้นมาเพื่อตอบสนอง เช่น การค้นหา ARP และการค้นหา NS รายการตัวกรองทั้งหมดมีการกำหนดไว้ใน ApfFilter
เนื่องจากโค้ดการสร้างโปรแกรม APF เป็นส่วนหนึ่งของโมดูล Network Stack คุณจึงใช้ การอัปเดต Mainline รายเดือนเพื่อเพิ่มตัวกรองใหม่และอัปเดตตรรกะการกรองได้
การแก้ไข APF
รายการต่อไปนี้อธิบายประวัติการแก้ไขของ APF
- APFv6: เปิดตัวใน Android 15 เวอร์ชันนี้รองรับการกรองแพ็กเก็ต มีตัวนับสำหรับการแก้ไขข้อบกพร่องและเมตริก และรองรับการส่งแพ็กเก็ต
- APFv4: เปิดตัวใน Android 10 เวอร์ชันนี้รองรับการกรองแพ็กเก็ตและมีตัวนับสำหรับการแก้ไขข้อบกพร่องและเมตริก
- APFv2: เปิดตัวใน Android 7 เวอร์ชันนี้รองรับการกรองแพ็กเก็ต
การผสานรวม APF
API ของ APF ระหว่างตัวตีความ APF กับฮาร์ดแวร์มีการกำหนดไว้ใน
apf_interpreter.h (APFv4, APFv6)
โค้ดเฟิร์มแวร์ Wi-Fi จะเรียกใช้ accept_packet() ใน APFv4 หรือ
apf_run() ใน APFv6 เพื่อพิจารณาว่าจะทิ้งแพ็กเก็ต (ค่าที่แสดงผลเป็น 0) หรือส่งไปยังโปรเซสเซอร์แอป (ค่าที่แสดงผลไม่เป็น 0) หากต้องส่งแพ็กเก็ต apf_run() จะแสดงผลเป็น 0 ด้วยเนื่องจากไม่จำเป็นต้องส่งแพ็กเก็ตไปยังโปรเซสเซอร์แอป หากเฟิร์มแวร์รองรับ
APFv6 เฟิร์มแวร์จะต้องติดตั้งใช้งาน API apf_allocate_buffer() และ
apf_transmit_buffer() ตัวตีความ APF จะเรียกใช้ API 2 รายการนี้ในระหว่างตรรกะการส่งแพ็กเก็ต คำสั่ง APF มีความยาวผันแปร คำสั่งแต่ละรายการมีความยาวอย่างน้อย 1 ไบต์ รหัสคำสั่ง APF มีการ
กำหนดไว้ใน apf.h สำหรับ APFv4 และมีการฝังไว้โดยตรงภายใน
apf_interpreter.c สำหรับ APFv6
APF อาศัยหน่วยความจำเฉพาะ หน่วยความจำใช้สำหรับทั้งโปรแกรม APF เองและสำหรับการจัดเก็บข้อมูล และชิปเซ็ตต้องไม่ล้างหรือเขียนหน่วยความจำ ยกเว้นผ่านเมธอด APF HAL ไบต์โค้ด APF ใช้ที่เก็บข้อมูลเพื่อจัดเก็บตัวนับสำหรับแพ็กเก็ตที่ยอมรับและทิ้ง คุณสามารถอ่านภูมิภาคข้อมูลจากเฟรมเวิร์ก Android ได้ คำสั่ง APF ประหยัดหน่วยความจำ แต่การเพิ่มศักยภาพในการประหยัดพลังงานและฟังก์ชันการทำงานให้สูงสุดต้องใช้กฎการกรองที่ซับซ้อนและไดนามิก ความซับซ้อนนี้จำเป็นต้องใช้หน่วยความจำส่วนหนึ่งบนชิปเซ็ต ข้อกำหนดหน่วยความจำขั้นต่ำสำหรับ APFv4 คือ 1024 ไบต์ ส่วน APFv6 ต้องใช้ 2048 ไบต์ อย่างไรก็ตาม เราขอแนะนำอย่างยิ่งให้คุณจัดสรร 4096 ไบต์สำหรับ APFv6 เพื่อยืนยันประสิทธิภาพสูงสุด ตัวตีความ APF ต้องคอมไพล์เป็นเฟิร์มแวร์ ทั้งตัวตีความ APFv4 และ APFv6 ได้รับการเพิ่มประสิทธิภาพสำหรับขนาดโค้ด ภายใต้สถาปัตยกรรม arm32 ตัวตีความ APFv4 ที่คอมไพล์แล้วมีขนาดประมาณ 1.8 KB ส่วนตัวตีความ APFv6 ที่ซับซ้อนกว่าพร้อมฟีเจอร์เพิ่มเติม (เช่น การรองรับการตรวจสอบผลรวมในตัวและโค้ดการบีบอัด DNS ในตัว) มีขนาดประมาณ 4 KB
ตัวกรอง APF สามารถทำงานร่วมกับตัวกรองอื่นๆ ที่เฉพาะเจาะจงของผู้จำหน่ายชิปเซ็ตภายในเฟิร์มแวร์ได้ คุณสามารถเลือกที่จะเรียกใช้ตรรกะการกรองก่อนหรือหลังกระบวนการกรอง APF ก็ได้ หากทิ้งแพ็กเก็ตก่อนที่จะไปถึงตัวกรอง APF ตัวกรอง APF จะไม่ประมวลผลแพ็กเก็ต
หากต้องการยืนยันฟังก์ชันการทำงานของตัวกรอง APF ที่ถูกต้อง เมื่อเปิด APF แล้ว ให้ตรวจสอบว่าเฟิร์มแวร์ให้สิทธิ์เข้าถึงแพ็กเก็ตทั้งหมดแก่ตัวกรอง APF ไม่ใช่แค่ส่วนหัว
ตัวอย่างโปรแกรม APF
ApfTest และ ApfFilterTest มีโปรแกรมทดสอบตัวอย่างที่
แสดงให้เห็นว่าตัวกรอง APF แต่ละรายการทำงานอย่างไร หากต้องการศึกษาโปรแกรมที่สร้างขึ้นจริง ให้แก้ไขกรณีทดสอบเพื่อพิมพ์โปรแกรมเป็นสตริงเลขฐานสิบหก
โฟลเดอร์ testdata มีโปรแกรม APFv4 ตัวอย่างสำหรับตัวกรอง APF RA
โฟลเดอร์ samples มีเครื่องมือ Python ที่สร้างโปรแกรมการทำงานแบบออฟโหลด APFv6
ดูรายละเอียดเพิ่มเติมได้ในเอกสารประกอบในไฟล์เครื่องมือ Python
แก้ไขข้อบกพร่องของ APF
หากต้องการตรวจสอบว่าเปิดใช้ APF ในอุปกรณ์หรือไม่ ให้แสดงโปรแกรมปัจจุบัน แสดงตัวนับปัจจุบัน และเรียกใช้คำสั่ง adb shell dumpsys network_stack ตัวอย่างคำสั่งนี้มีดังนี้
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เอาต์พุตสำหรับคำสั่ง adb shell dumpsys network_stack ตัวอย่างนี้ประกอบด้วยสิ่งต่อไปนี้
ApfCapabilities{version: 4, maxSize: 4096, format: 1}: หมายความว่าชิป Wi-Fi รองรับ APF (เวอร์ชัน 4)Last program: ส่วนนี้คือไบนารีโปรแกรม APF ที่ติดตั้งล่าสุดในรูปแบบสตริงเลขฐานสิบหกAPF packet counters: ส่วนนี้แสดงจำนวนแพ็กเก็ตที่ APF ส่งผ่านหรือทิ้ง และเหตุผลที่เฉพาะเจาะจง
หากต้องการถอดรหัสและแยกโค้ดออกเป็นภาษาแอสเซมเบลอร์ที่มนุษย์อ่านออกได้ ให้ใช้
เครื่องมือ apf_disassembler หากต้องการคอมไพล์ไบนารีที่เรียกใช้งานได้ ให้เรียกใช้คำสั่ง m apf_disassembler ตัวอย่างวิธีใช้เครื่องมือ 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
......หากต้องการตรวจสอบผลลัพธ์ APF แบบออฟไลน์ ให้ใช้เครื่องมือ apf_run หากต้องการคอมไพล์ไบนารีที่เรียกใช้งานได้ ให้เรียกใช้คำสั่ง m apf_run เครื่องมือ apf_run รองรับทั้งตัวตีความ APFv4 และ APFv6
ต่อไปนี้คือคู่มือสำหรับคำสั่ง apf_run โดยค่าเริ่มต้น คำสั่ง apf_run จะทำงานในตัวตีความ APFv4 การส่งอาร์กิวเมนต์ --v6 ไปยัง apf_run จะทำให้คำสั่งทำงานกับตัวตีความ APFv6 อาร์กิวเมนต์อื่นๆ ทั้งหมดสามารถใช้ได้กับทั้ง APFv4 และ 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.ต่อไปนี้คือตัวอย่างการส่งแพ็กเก็ตไปยัง APF เพื่อตรวจสอบว่าทิ้งหรือส่งแพ็กเก็ตได้หรือไม่
หากต้องการแสดงสตริงไบนารีเลขฐานสิบหกของแพ็กเก็ตดิบ ให้ใช้ตัวเลือก --packet หากต้องการแสดงสตริงไบนารีเลขฐานสิบหกของภูมิภาคข้อมูล ซึ่ง
ใช้เพื่อจัดเก็บ ตัวนับ APF ให้ใช้ตัวเลือก --data เนื่องจากตัวนับแต่ละรายการมีความยาว 4 ไบต์ ภูมิภาคข้อมูลจึงต้องมีความยาวเพียงพอเพื่อให้แน่ใจว่าจะไม่มีบัฟเฟอร์ล้น
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001หากต้องการตรวจสอบผลลัพธ์ APF กับไฟล์ pcap ที่ tcpdump สร้างขึ้น ให้ใช้คำสั่ง apf_run ดังนี้
out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006eaหากต้องการทดสอบความสามารถในการส่งของ APFv6 ให้ใช้คำสั่ง apf_run ดังนี้
$ 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
เมื่อใช้พารามิเตอร์ --trace เครื่องมือ apf_run จะแสดงเอาต์พุตโดยละเอียดของแต่ละขั้นตอนในการดำเนินการของตัวตีความ ซึ่งมีประโยชน์สำหรับการแก้ไขข้อบกพร่อง ในตัวอย่างนี้ คุณจะป้อนแพ็กเก็ตการค้นหา ARP ลงในโปรแกรม APF
เอาต์พุตแสดงว่ามีการทิ้งแพ็กเก็ตการค้นหา ARP แต่มีการสร้างแพ็กเก็ตการตอบกลับ
รายละเอียดของแพ็กเก็ตที่สร้างขึ้นนี้จะแสดงในส่วน transmitted packet
ปัญหาการผสานรวมที่พบได้ทั่วไป
ส่วนนี้จะเน้นปัญหาที่พบได้ทั่วไปหลายอย่างในระหว่างการผสานรวม APF
- การล้างภูมิภาคข้อมูลโดยไม่คาดคิด: หน่วยความจำ APF ต้องใช้สำหรับ APF เท่านั้น โดยมีเพียงโค้ดตัวตีความหรือโค้ดเฟรมเวิร์ก (ผ่าน HAL API) เท่านั้นที่ได้รับอนุญาตให้แก้ไขภูมิภาคหน่วยความจำ APF
- ปัญหาการติดตั้งโปรแกรม APF ขนาด X ไบต์ (X <=
maxLen): เฟิร์มแวร์ต้องรองรับการอ่านหรือเขียนโปรแกรมที่มีความยาวสูงสุดmaxLenโดยไม่มีข้อผิดพลาด การหยุดทำงาน หรือการตัดทอน การเขียนต้องไม่เปลี่ยนแปลงไบต์ใดๆ ระหว่างXกับmaxLen - การติดตั้งใช้งาน APF ในโค้ดไดรเวอร์: ควรติดตั้งใช้งาน APF ภายในเฟิร์มแวร์เท่านั้น ไม่ใช่โค้ดไดรเวอร์ มิฉะนั้นจะไม่มีประโยชน์ในการประหยัดพลังงานเนื่องจาก CPU ต้องตื่นขึ้นมาเพื่อประมวลผลแพ็กเก็ต
- ค่า
filter_ageหรือfilter_age_16384thไม่ถูกต้อง: ค่าfilter_age(APFv4) และfilter_age_16384th(APFv6) ต้อง ส่งไปยังฟังก์ชันaccept_packet()และapf_run()อย่างถูกต้อง ดู รายละเอียดเกี่ยวกับการคำนวณfilter_age_16384thได้ในเอกสารประกอบในapf_interpreter.h - ไม่ได้เปิดใช้ APF เมื่อจำเป็น: ต้องเปิดใช้ APF เมื่อหน้าจอปิดอยู่และลิงก์ Wi-Fi ไม่ได้ใช้งานหรือการรับส่งข้อมูลน้อยกว่า 10 Mbps
- ส่งแพ็กเก็ตที่ถูกตัดทอนไปยัง
accept_packet()หรือapf_run(): แพ็กเก็ตแบบ ยูนิคาสต์ บรอดคาสต์ และมัลติคาสต์ทั้งหมดที่ส่งไปยังaccept_packet()หรือapf_run()ต้องสมบูรณ์ การส่งแพ็กเก็ตที่ถูกตัดทอนไปยัง APF ไม่ถูกต้อง
การทดสอบ APF
ตั้งแต่ Android 15 เป็นต้นไป Android มีกรณีทดสอบชุดเครื่องมือทดสอบความเข้ากันได้ (CTS) ทั้งแบบอุปกรณ์เดียวและหลายอุปกรณ์สำหรับการผสานรวมตัวกรอง APF และตัวตีความ APF เพื่อยืนยันฟังก์ชันการทำงานของ APF ที่ถูกต้อง รายละเอียดวัตถุประสงค์ของกรณีทดสอบแต่ละรายการมีดังนี้
- การทดสอบการผสานรวม ApfFilter และ apf_interpreter:
ยืนยันว่า
ApfFilterสร้างไบต์โค้ดที่ถูกต้อง และapf_interpreterเรียกใช้โค้ดอย่างถูกต้องเพื่อให้ได้ผลลัพธ์ที่คาดไว้ - **CTS แบบอุปกรณ์เดียวของ APF**: ใช้อุปกรณ์เดียวเพื่อทดสอบฟังก์ชันการทำงาน
ของ APF ในชิปเซ็ต Wi-Fi ยืนยันสิ่งต่อไปนี้
- APF จะเปิดขึ้นเมื่อหน้าจอปิดอยู่และการรับส่งข้อมูล Wi-Fi น้อยกว่า 10 Mbps
- มีการประกาศความสามารถของ APF อย่างถูกต้อง
- การดำเนินการอ่านและเขียนในภูมิภาคหน่วยความจำ APF สำเร็จ และภูมิภาคหน่วยความจำไม่ได้รับการแก้ไขโดยไม่คาดคิด
- มีการส่งอาร์กิวเมนต์ไปยัง
accept_packet()หรือapf_run()อย่างถูกต้อง - เฟิร์มแวร์ที่ผสานรวมกับ APFv4/APFv6 สามารถทิ้งแพ็กเก็ตได้
- เฟิร์มแวร์ที่ผสานรวมกับ APFv6 สามารถตอบกลับแพ็กเก็ตได้
- **CTS แบบหลายอุปกรณ์ของ APF**: ใช้อุปกรณ์ 2 เครื่อง (เครื่องส่ง 1 เครื่องและเครื่องรับ
1 เครื่อง) เพื่อทดสอบลักษณะการกรองของ APF มีการสร้างแพ็กเก็ตประเภทต่างๆ ในฝั่งเครื่องส่ง และการทดสอบจะยืนยันว่ามีการทิ้ง ส่งผ่าน หรือตอบกลับแพ็กเก็ตอย่างถูกต้องหรือไม่ตามกฎที่กำหนดค่าไว้ใน
ApfFilterเพื่อยืนยันฟังก์ชันการทำงานของ APF ที่ถูกต้อง
วิธีการทดสอบการผสานรวมเพิ่มเติม
นอกจากนี้ เราขอแนะนำอย่างยิ่งให้คุณรวมการทดสอบ APF ไว้ในชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์
การรวมการทดสอบ APF ไว้ในชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์มีความสำคัญอย่างยิ่งในการยืนยันฟังก์ชันการทำงานของ APF ที่เหมาะสมในสถานการณ์การเชื่อมต่อ Wi-Fi ที่ซับซ้อน เช่น สถานการณ์การเชื่อมต่อ Wi-Fi แบบ Make-Before-Break หรือการโรมมิ่ง ดูวิธีการโดยละเอียดเกี่ยวกับการทดสอบการผสานรวมได้ในส่วนต่อไปนี้
สิ่งที่ต้องมีก่อน
เมื่อทำการทดสอบการผสานรวม ให้ทำดังนี้
- ต้องเปิดใช้ APF ตลอดกรณีทดสอบการผสานรวมทั้งหมด (เช่น การโรมมิ่ง, Make-Before-Break)
- ล้างหน่วยความจำ APF เมื่อเริ่มการทดสอบแต่ละครั้ง
- ติดตั้งหรือติดตั้งโปรแกรม APF ใหม่ทุก 5 นาทีระหว่างการทดสอบ
สถานการณ์ทดสอบ
APF ต้องทำงานอยู่ตลอดการทดสอบการผสานรวม เอกสารนี้มีโปรแกรม APF 2 รายการที่คุณสามารถติดตั้งระหว่างการทดสอบ โปรแกรมอยู่ในรูปแบบสตริงเลขฐานสิบหก และคุณต้องแปลงสตริงเลขฐานสิบหกเป็นไบนารีและติดตั้งโปรแกรมลงในเฟิร์มแวร์เพื่อให้ apf_interpreter เรียกใช้โปรแกรมได้ ระหว่างการทดสอบการผสานรวม คุณควรส่งแพ็กเก็ตที่คาดว่าจะทริกเกอร์ตรรกะการกรองในโปรแกรม 1 และโปรแกรม 2
โปรแกรม APF 1
เมื่อหน้าจออุปกรณ์เปิดอยู่ ให้ติดตั้ง โปรแกรม APF 1 โปรแกรมนี้สามารถทิ้งแพ็กเก็ตที่ไม่เป็นอันตรายซึ่งไม่ส่งผลต่อฟังก์ชันการทำงานของอุปกรณ์ แพ็กเก็ตเหล่านี้ใช้เพื่อทดสอบว่า APF กรองการจราจรของข้อมูลในเครือข่ายอย่างถูกต้องหรือไม่
ตรรกะของโปรแกรม APF 1 มีดังนี้
- ทิ้งและเพิ่มตัวนับ:
- ค่า EtherType:
0x88A2,0x88A4,0x88B8,0x88CD,0x88E1,0x88E3 - แพ็กเก็ตการค้นหาหรือคำขอ DHCP ของ IPv4
- แพ็กเก็ต RS
- ค่า EtherType:
- ส่งผ่านและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด
ไบต์โค้ดของโปรแกรม APF 1 มีดังนี้
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
โปรแกรม APF 2
เมื่อหน้าจออุปกรณ์ปิดอยู่ ให้ติดตั้ง โปรแกรม APF 2 โปรแกรมนี้จะกรองแพ็กเก็ตทั้งหมดที่ โปรแกรม APF 1 กรอง รวมถึงแพ็กเก็ตคำขอ ping หากต้องการยืนยันว่าติดตั้ง โปรแกรม APF 2 อย่างถูกต้อง ให้ส่งแพ็กเก็ต ping ไปยังอุปกรณ์ที่ทดสอบ
ตรรกะของโปรแกรม APF 2 มีดังนี้
- ทิ้งและเพิ่มตัวนับ:
- ค่า EtherType:
0x88A2,0x88A4,0x88B8,0x88CD,0x88E1,0x88E3 - แพ็กเก็ตการค้นหาหรือคำขอ DHCP ของ IPv4
- แพ็กเก็ต RS
- ค่า EtherType:
- ทิ้งและเพิ่มตัวนับ: แพ็กเก็ตคำขอ ping ICMP
- ส่งผ่านและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด
ไบต์โค้ดของโปรแกรม APF 2 มีดังนี้
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
การยืนยันข้อมูล
หากต้องการยืนยันว่าโปรแกรม APF ทำงานและส่งผ่านหรือทิ้งแพ็กเก็ตอย่างถูกต้อง ให้ทำดังนี้
- ดึงและยืนยันภูมิภาคข้อมูล APF ทุก 5 นาที
- อย่าล้างตัวนับ
- สร้างแพ็กเก็ตทดสอบเพื่อทริกเกอร์กฎตัวกรองแต่ละรายการ
ยืนยันการเพิ่มตัวนับโดยใช้ตำแหน่งหน่วยความจำต่อไปนี้
ชื่อตัวนับ ตำแหน่งหน่วยความจำ 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 สำหรับโปรแกรม APF 1 และโปรแกรม APF 2
Pseudocode ต่อไปนี้อธิบายตรรกะของโปรแกรม APF 1 และโปรแกรม 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