فیلتر بسته Android (APF) به چارچوب اجازه می دهد منطق فیلتر کردن بسته های سخت افزاری را در زمان اجرا کنترل کند. این به سیستم اجازه میدهد با انداختن بستهها در سختافزار در مصرف انرژی صرفهجویی کند، در حالی که به چارچوب اندروید اجازه میدهد قوانین فیلتر را در زمان اجرا بر اساس شرایط شبکه تغییر دهد.
نمای کلی APF
APF از دو جزء اصلی تشکیل شده است:
- مفسر APF روی سخت افزار شبکه (معمولاً چیپست Wi-Fi) اجرا می شود. مفسر APF بایت کد APF را روی بسته های دریافت شده توسط سخت افزار اجرا می کند و تصمیم می گیرد که آنها را بپذیرد یا رها کند.
- کد تولید برنامه APF روی CPU اصلی اجرا می شود. کد برنامه های APF را با توجه به وضعیت شبکه و دستگاه ایجاد و به روز می کند.
روش های Wi-Fi HAL به فریم ورک اندروید اجازه می دهد بایت کد برنامه APF را نصب کند و شمارنده های فعلی را بخواند. ماژول Network Stack Mainline می تواند بایت کد برنامه APF را در هر زمانی که APF در حال اجرا است به روز کند.
چندین فیلتر APF پیاده سازی شده است. به عنوان مثال، APF شامل فیلترهایی برای حذف اترتیپهای غیرمجاز، فیلتر کردن بستههای تبلیغاتی روتر IPv6 (RA)، فیلتر کردن ترافیک چندپخشی و پخش در صورت عدم نگه داشتن قفل چندپخشی، رها کردن بستههای DHCP برای میزبانهای دیگر، و حذف پروتکل وضوح آدرس ناخواسته (ARP) است. و (کشف همسایه) بسته های ND. لیست کامل فیلترها در ApfFilter
تعریف شده است.
از آنجایی که کد تولید برنامه APF بخشی از ماژول Network Stack است، منطق فیلترینگ را می توان از طریق به روز رسانی ماهانه Mainline به روز کرد و فیلترهای جدید اضافه کرد.
ادغام APF
API APF در apf_interpreter.h
تعریف شده است. کد میانافزار Wi-Fi int accept_packet()
را فراخوانی میکند تا مشخص کند بسته باید حذف شود (مقدار بازگشتی صفر) یا ارسال شود (مقدار برگشتی غیر صفر). دستورالعمل های APF دارای طول متغیر هستند. هر دستورالعمل حداقل یک بایت طول دارد. کدهای دستورالعمل APF در apf.h
تعریف شده اند.
APF به حافظه اختصاصی متکی است. حافظه هم برای خود برنامه APF و هم برای ذخیره سازی داده ها استفاده می شود و حافظه نباید توسط چیپست پاک یا نوشته شود مگر از طریق روش های APF HAL. بایت کد APF از ذخیره سازی داده برای ذخیره شمارنده برای بسته های پذیرفته شده و حذف شده استفاده می کند. منطقه داده را می توان از چارچوب Android خواند. حداقل مقدار حافظه موجود برای APF باید 1024 بایت باشد.
اشکال زدایی 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
آورده شده است.
برای ارائه رشته باینری هگزا بسته خام، از گزینه --packet
استفاده کنید. برای ارائه رشته باینری هگز ناحیه داده که برای ذخیره شمارنده 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