فلتر حزم Android

يتيح فلتر حزم Android (APF) لإطار العمل التحكم في منطق فلترة حزم الأجهزة في وقت التشغيل. يتيح ذلك للنظام توفير الطاقة من خلال طرح الحِزم في الأجهزة، مع السماح لإطار عمل Android بتغيير قواعد الفلترة في وقت التشغيل استنادًا إلى ظروف الشبكة.

نظرة عامة على APF

يتألّف هذا الإطار من مكوّنَين أساسيَّين:

  • يتم تشغيل مترجم APF على أجهزة الشبكات (عادةً شريحة Wi-Fi). ويشغِّل برنامج ترجمة APF رمز بايت APF على الحزم التي يستلمها الجهاز ويقرر ما إذا كان سيتم قبولها أو إفلاتها.
  • يعمل رمز إنشاء برنامج APF على وحدة المعالجة المركزية (CPU) الرئيسية. ينشئ الرمز برامج APF ويحدِّثها وفقًا لحالة الشبكة والجهاز.

تتيح طرق HAL لشبكة Wi-Fi لإطار عمل Android تثبيت رمز بايت برنامج APF وقراءة العدادات الحالية. يمكن لوحدة Network Stack Mainline تعديل رمز البايت لبرنامج APF في أي وقت أثناء تشغيل APF.

تم تنفيذ العديد من فلاتر APF. على سبيل المثال، يشتمل APF على فلاتر لإسقاط أنواع ethertype غير المسموح بها، وتصفية حزم إعلان جهاز توجيه IPv6 (RA) وتصفية حركة بيانات البث المتعدد وبثها في حال عدم تثبيت قفل البث المتعدد، وإسقاط حزم DHCP للمضيفين الآخرين، وإسقاط حزم بروتوكول دقة العنوان (ARP) و (اكتشاف الجيران) حزم ND. تم تحديد القائمة الكاملة للفلاتر في ApfFilter.

ولأنّ رمز إنشاء برنامج APF هو جزء من وحدة "حزمة الشبكة"، يمكن تعديل منطق الفلترة وإضافة فلاتر جديدة من خلال تحديثات Mainline الشهرية.

دمج APF

يتم تحديد APF API في 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