يتيح Android Packet Filter (APF) لإطار العمل التحكم في منطق تصفية حزم الأجهزة في وقت التشغيل. يتيح ذلك للنظام توفير الطاقة عن طريق إسقاط الحزم في الأجهزة، مع السماح لإطار عمل Android بتغيير قواعد التصفية في وقت التشغيل بناءً على ظروف الشبكة.
نظرة عامة على APF
يتكون APF من عنصرين رئيسيين:
- يعمل مترجم APF على أجهزة الشبكة (عادةً مجموعة شرائح Wi-Fi). يقوم مترجم APF بتشغيل كود APF الثانوي على الحزم التي يتلقاها الجهاز ويقرر ما إذا كان سيتم قبولها أو إسقاطها.
- يعمل رمز إنشاء برنامج APF على وحدة المعالجة المركزية الرئيسية. يقوم الكود بإنشاء وتحديث برامج APF وفقًا لحالة الشبكة والجهاز.
تسمح طرق Wi-Fi HAL لإطار عمل Android بتثبيت الرمز الثانوي لبرنامج APF وقراءة العدادات الحالية. يمكن لوحدة Network Stack Mainline تحديث الرمز الثانوي لبرنامج APF في أي وقت أثناء تشغيل APF.
هناك العديد من مرشحات APF المطبقة. على سبيل المثال، يتضمن APF عوامل تصفية لإسقاط أنواع الأثيرات غير المسموح بها، وتصفية حزم إعلان جهاز توجيه IPv6 (RA)، وتصفية البث المتعدد وحركة البث إذا لم يتم تعليق قفل البث المتعدد، وإسقاط حزم DHCP للمضيفين الآخرين، وإسقاط بروتوكول تحليل العناوين غير المرغوب فيه (ARP). و(اكتشاف الجوار) حزم ND. يتم تعريف القائمة الكاملة للمرشحات في ApfFilter
.
نظرًا لأن كود إنشاء برنامج APF جزء من وحدة Network Stack، فيمكن تحديث منطق التصفية وإضافة مرشحات جديدة من خلال تحديثات Mainline الشهرية.
التكامل APF
تم تعريف واجهة برمجة تطبيقات 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