ตัวกรองแพ็กเก็ต Android (APF) ช่วยให้เฟรมเวิร์กควบคุมตรรกะการกรองแพ็กเก็ตฮาร์ดแวร์ขณะรันไทม์ได้ ซึ่งช่วยให้ระบบประหยัดพลังงานด้วยการทิ้งแพ็กเก็ตในฮาร์ดแวร์ และช่วยให้เฟรมเวิร์ก Android เปลี่ยนกฎการกรองขณะรันไทม์ตามสภาพเครือข่ายได้
ภาพรวมของ APF
APF ประกอบด้วยองค์ประกอบหลัก 2 ส่วน ได้แก่
- โปรแกรมแปลภาษา APF ทำงานบนฮาร์ดแวร์เครือข่าย (โดยทั่วไปคือชิปเซ็ต Wi-Fi) โปรแกรมแปลภาษา APF จะเรียกใช้ไบต์โค้ด APF ในแพ็กเก็ตที่ได้รับจากฮาร์ดแวร์และตัดสินใจว่าจะยอมรับ ทิ้ง หรือตอบกลับแพ็กเก็ตเหล่านั้น
- โค้ดการสร้างโปรแกรม APF จะทำงานบน CPU หลัก โค้ดจะสร้างและอัปเดตโปรแกรม APF ตามสถานะเครือข่ายและอุปกรณ์
เมธอด Wi-Fi HAL ช่วยให้เฟรมเวิร์ก Android ติดตั้งโปรแกรม APF ไปป์ไลน์ และอ่านตัวนับปัจจุบันได้ โมดูล Mainline สแต็กเครือข่ายสามารถอัปเดตไบต์โค้ดของโปรแกรม APF ได้ทุกเมื่อขณะที่ APF ทำงานอยู่
มีการใช้ตัวกรอง APF หลายรายการ ตัวอย่างเช่น APF มีตัวกรองเพื่อทิ้งอีเทอร์ประเภทที่ไม่อนุญาต กรองแพ็กเก็ตการโฆษณาเราเตอร์ IPv6 (RA) กรองการรับส่งข้อมูลมัลติแคสต์และบรอดแคสต์หากไม่ได้ล็อกมัลติแคสต์ไว้ ทิ้งแพ็กเก็ต DHCP สำหรับโฮสต์อื่นๆ และทิ้งแพ็กเก็ตโปรโตคอลการแก้ไขที่อยู่ (ARP) และแพ็กเก็ตการค้นหาเพื่อนบ้าน (ND) ที่ไม่ได้รับอนุญาต หากเฟิร์มแวร์รองรับ APFv6
ApfFilter
จะสร้างกฎเพื่อตอบกลับประเภทแพ็กเก็ตทั่วไปด้วย ซึ่งปกติแล้วจะต้องทำให้ CPU ตื่นขึ้นเพื่อตอบกลับ เช่น การค้นหา ARP และการค้นหา NS รายการตัวกรองทั้งหมดจะระบุไว้ใน ApfFilter
เนื่องจากโค้ดการสร้างโปรแกรม APF เป็นส่วนหนึ่งของโมดูลสแต็กเครือข่าย คุณจึงใช้ [การอัปเดตหลักรายเดือนเพื่อเพิ่มตัวกรองใหม่และอัปเดตตรรกะการกรองได้
การแก้ไข 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 คือ 1,024 ไบต์ ส่วน APFv6 ต้องใช้ 2,048 ไบต์ อย่างไรก็ตาม เราขอแนะนําอย่างยิ่งให้จัดสรร 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 แต่ละรายการ หากต้องการศึกษาโปรแกรมที่สร้างขึ้นจริง ให้แก้ไขเคสทดสอบเพื่อพิมพ์โปรแกรมเป็นสตริงฐาน 16
โฟลเดอร์ 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 ที่ติดตั้งล่าสุดในรูปแบบสตริงฐาน 16APF 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.
ต่อไปนี้คือตัวอย่างการส่งแพ็กเก็ต 1 รายการไปยัง APF เพื่อตรวจสอบว่าระบบจะทิ้งหรือส่งแพ็กเก็ตได้หรือไม่
หากต้องการแสดงแพ็กเก็ตดิบในรูปแบบสตริงไบนารีฐานสิบหก ให้ใช้ตัวเลือก --packet
หากต้องการระบุสตริงไบนารีฐาน 16 ของเขตข้อมูล ซึ่งใช้เพื่อจัดเก็บตัวนับ APF ให้ใช้ --data option
เนื่องจากตัวนับแต่ละรายการมีความยาว 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 ไว้ในชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์
การผสานรวมการทดสอบ APF เข้ากับชุดทดสอบการผสานรวม Wi-Fi ของเฟิร์มแวร์มีความสําคัญต่อการยืนยันฟังก์ชันการทํางานของ APF ที่ถูกต้องในสถานการณ์การเชื่อมต่อ Wi-Fi ที่ซับซ้อน เช่น สถานการณ์การเชื่อมต่อ Wi-Fi แบบพักก่อนหรือโรมมิง ดูวิธีการโดยละเอียดเกี่ยวกับการทดสอบการผสานรวมได้ที่ส่วนต่อไปนี้
สิ่งที่ต้องมีก่อน
เมื่อทำการทดสอบการผสานรวม ให้ทำดังนี้
- ต้องเปิดใช้ APF ในทุกกรณีทดสอบการผสานรวม (เช่น การโรมมิง การทำก่อนหยุดพัก)
- ล้างหน่วยความจํา APF เมื่อเริ่มการทดสอบแต่ละครั้ง
- ติดตั้งหรือติดตั้งโปรแกรม APF อีกครั้งทุก 5 นาทีในระหว่างการทดสอบ
สถานการณ์การทดสอบ
APF ต้องทำงานอยู่ตลอดการทดสอบการผสานรวม เอกสารนี้มีโปรแกรม APF 2 รายการที่ติดตั้งได้ในระหว่างการทดสอบ โปรแกรมอยู่ในรูปแบบสตริงฐานสิบหก และผู้ทดสอบต้องแปลงสตริงฐานสิบหกเป็นไบนารีและติดตั้งลงในเฟิร์มแวร์เพื่อให้apf_interpreter
เรียกใช้โปรแกรมได้ ในระหว่างการทดสอบการผสานรวม ผู้ทดสอบควรส่งแพ็กเก็ตที่คาดว่าจะทริกเกอร์ตรรกะการกรองในโปรแกรม 1 และโปรแกรม 2
โปรแกรม APF 1
เมื่อหน้าจออุปกรณ์เปิดอยู่ ให้ติดตั้ง APF program 1 โปรแกรมนี้จะทิ้งแพ็กเก็ตที่ไม่เป็นอันตรายซึ่งไม่ส่งผลต่อฟังก์ชันการทำงานของอุปกรณ์ ระบบจะใช้แพ็กเก็ตเหล่านี้เพื่อทดสอบว่า APF กรองการเข้าชมเครือข่ายอย่างถูกต้องหรือไม่
ตรรกะโปรแกรม APF 1 มีดังนี้
- ตัวนับการลดลงและเพิ่มขึ้น
- ค่า EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- แพ็กเก็ตการค้นพบหรือคำขอ DHCP ของ IPv4
- แพ็กเกต RS
- ค่า EtherType:
- ผ่านและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด
โค้ด 1 ไบต์ของโปรแกรม APF มีดังนี้
6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
โปรแกรม APF 2
เมื่อหน้าจออุปกรณ์ปิดอยู่ ให้ติดตั้ง APF program 2 โปรแกรมนี้จะกรองแพ็กเก็ตทั้งหมดที่โปรแกรม APF 1 กรองออก รวมถึงแพ็กเก็ตคำขอ ping หากต้องการยืนยันว่าติดตั้ง APF program 2 อย่างถูกต้อง ให้ส่งแพ็กเก็ต ping ไปยังอุปกรณ์ทดสอบ
ตรรกะโปรแกรม APF 2 มีดังนี้
- ตัวนับการลดลงและเพิ่มขึ้น
- ค่า EtherType:
0x88A2
,0x88A4
,0x88B8
,0x88CD
,0x88E1
,0x88E3
- แพ็กเก็ตการค้นพบหรือคำขอ DHCP ของ IPv4
- แพ็กเกต RS
- ค่า EtherType:
- ลดลงและเพิ่มตัวนับ: แพ็กเก็ตคำขอ ping ICMP
- ส่งและเพิ่มตัวนับ: แพ็กเก็ตอื่นๆ ทั้งหมด
โค้ด 2 ไบต์ของโปรแกรม APF มีดังนี้
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]
รหัสจำลองสำหรับโปรแกรม APF 1 และโปรแกรม APF 2
รหัสจำลองต่อไปนี้อธิบายตรรกะของโปรแกรม 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