فلتر حزم Android

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

نظرة عامة على "إطار عمل أمان التطبيقات"

يتألف "إطار عمل أمان التطبيقات" من مكوّنَين رئيسيَّين:

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

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

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

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

مراجعة APF

توضّح القائمة التالية سجلّ مراجعة "تنسيق إعلانات التطبيقات":

  • APFv6: تم طرح هذا الإصدار في Android 15، وهو يتيح فلترة الحِزم، ويتضمّن عدّادات لتصحيح الأخطاء والمقاييس، كما يتيح إرسال الحِزم.
  • الإصدار 4 من APF: تم طرح هذا الإصدار في Android 10، وهو يتيح فلترة الحِزم ويتضمّن عدّادات لتصحيح الأخطاء والمقاييس.
  • APFv2: تم طرح هذا الإصدار في Android 7، وهو يتيح فلترة الحِزم.

دمج APF

يتم تحديد واجهات برمجة التطبيقات APF بين برنامج تحليل APF والأجهزة في apf_interpreter.h (APFv4, APFv6). يستدعي رمز البرامج الثابتة لشبكة Wi-Fi accept_packet() في APFv4 أو apf_run() في APFv6 لتحديد ما إذا كان يجب تجاهل الحزمة (قيمة الإرجاع صفر) أو تمريرها إلى معالج التطبيق (قيمة الإرجاع غير صفر). إذا كان يجب إرسال حزمة، تعرض الدالة apf_run() أيضًا القيمة صفر لأنّه لا يلزم تمرير الحزمة إلى معالج التطبيق. إذا كانت البرامج الثابتة تتوافق مع APFv6، يجب أن تنفّذ واجهات برمجة التطبيقات apf_allocate_buffer() و apf_transmit_buffer(). يطلب برنامج تحليل APF هاتين الواجهتين أثناء منطق نقل الحِزم. تعليمات APF متغيرة الطول. يبلغ طول كل تعليمات بايت واحد على الأقل. يتم تحديد رموز تعليمات APF في apf.h بالنسبة إلى APFv4، ويتم تضمينها مباشرةً في apf_interpreter.c بالنسبة إلى APFv6.

تعتمد ميزة "الاستجابة السريعة للتطبيقات" على ذاكرة مخصّصة. يتم استخدام الذاكرة لكل من برنامج APF نفسه ولتخزين البيانات، ويجب ألا تتم إزالة الذاكرة أو الكتابة فيها بواسطة مجموعة الشرائح إلا من خلال طرق APF HAL. يستخدم رمز APF البايت تخزين البيانات لتخزين عدّادات للحِزم المقبولة والمرفوضة. يمكن قراءة منطقة البيانات من إطار عمل Android. تتسم تعليمات APF بكفاءة استخدام الذاكرة، ولكنّ تحقيق أقصى استفادة من إمكاناتها في توفير الطاقة والوظائف يتطلب قواعد تصفية معقّدة وديناميكية. وتتطلّب هذه التعقيدات جزءًا مخصّصًا من الذاكرة المضمّنة في مجموعة الشرائح. الحد الأدنى لمتطلبات الذاكرة في APFv4 هو 1024 بايت، بينما يتطلب APFv6 مساحة 2048 بايت. ومع ذلك، ننصحك بشدة بتخصيص 4096 بايت لـ APFv6 لضمان تحقيق الأداء الأمثل. يجب تجميع برنامج تحليل APF في البرامج الثابتة. تم تحسين كلّ من برامج تحليل APFv4 وAPFv6 لتناسب حجم الرمز. في بنية arm32 الأساسية، يبلغ حجم برنامج ترجمة APFv4 المجمَّع حوالي 1.8 كيلوبايت، بينما يبلغ حجم برنامج ترجمة APFv6 الأكثر تعقيدًا، والذي يتضمّن ميزات إضافية (مثل التوافق الأصلي مع المجموع الاختباري ورمز فك الضغط الأصلي لنظام أسماء النطاقات)، حوالي 4 كيلوبايت.

يمكن أن تعمل فلاتر 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 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) بتعديل منطقة ذاكرة APF.
  • مشاكل التثبيت في برامج APF التي يبلغ حجمها X بايت (X <= maxLen): يجب أن يتيح البرنامج الثابت قراءة أو كتابة أي طول للبرنامج يصل إلى maxLen بدون حدوث أخطاء أو أعطال أو اقتطاع. يجب ألا تؤدي عمليات الكتابة إلى تغيير أي بايتات بين X وmaxLen.
  • تنفيذ APF في رمز برنامج التشغيل: يجب تنفيذ APF فقط ضمن البرامج الثابتة، وليس في رمز برنامج التشغيل. وفي ما عدا ذلك، لن تكون هناك أي فوائد لتوفير الطاقة لأنّ وحدة المعالجة المركزية تحتاج إلى التنشيط لمعالجة الحزمة.
  • قيم filter_age أو filter_age_16384th غير صحيحة: يجب تمرير قيمتَي filter_age (APFv4) وfilter_age_16384th (APFv6) بشكل صحيح إلى الدالتَين accept_packet() وapf_run(). للحصول على تفاصيل حول كيفية احتساب filter_age_16384th، يُرجى الرجوع إلى المستندات في apf_interpreter.h.
  • عدم تفعيل ميزة "توفير الطاقة التكيّفي" عند الحاجة إليها: يجب تفعيل ميزة "توفير الطاقة التكيّفي" عندما تكون الشاشة مطفأة ويكون رابط Wi-Fi غير نشط أو تكون حركة البيانات أقل من 10 ميغابايت في الثانية.
  • حِزم البيانات المقتطعة التي تم تمريرها إلى 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. يؤكّد ما يلي:
    • يتم تفعيل ميزة &quot;توفير الطاقة التكيّفي&quot; عندما تكون الشاشة مطفأة ويكون معدّل نقل بيانات شبكة Wi-Fi أقل من 10 ميغابايت في الثانية.
    • يتم الإعلان عن إمكانات APF بشكل صحيح.
    • تنجح عمليات القراءة والكتابة في منطقة ذاكرة APF، ولا يتم تعديل منطقة الذاكرة بشكل غير متوقّع.
    • يتم تمرير الوسيطات بشكل صحيح إلى accept_packet() أو apf_run().
    • يمكن للبرامج الثابتة المدمجة مع APFv4/APFv6 إسقاط الحِزم.
    • يمكن للبرامج الثابتة المدمجة مع APFv6 الرد على الحِزم.
  • مجموعة أدوات اختبار التوافق (CTS) للأجهزة المتعددة في APF: تستخدِم جهازَين (أحدهما جهاز إرسال والآخر جهاز استقبال) لاختبار سلوك الفلترة في APF. يتم إنشاء أنواع مختلفة من الحِزم على جانب المُرسِل، ويؤكّد الاختبار ما إذا كان يتم إسقاطها أو تمريرها أو الرد عليها بشكل صحيح استنادًا إلى القواعد التي تم ضبطها في ApfFilter.

تعليمات إضافية لاختبارات الدمج

بالإضافة إلى ذلك، ننصح بشدة مورّدي شرائح المعالجة بدمج اختبارات APF في مجموعات اختبارات دمج Wi-Fi الخاصة بالبرامج الثابتة.

يُعد دمج اختبار APF في مجموعات اختبارات دمج Wi-Fi في البرامج الثابتة أمرًا بالغ الأهمية للتحقّق من وظائف APF بشكل سليم في سيناريوهات اتصال Wi-Fi المعقّدة، مثل سيناريوهات الاتصال بشبكة Wi-Fi قبل قطع الاتصال أو أثناء التجوال. يمكنك الاطّلاع على التعليمات التفصيلية حول كيفية إجراء اختبارات الدمج في القسم التالي.

المتطلّبات الأساسية

عند إجراء اختبارات الدمج، اتّبِع الخطوات التالية:

  • يجب تفعيل APF في جميع حالات اختبار التكامل (على سبيل المثال، التجوال، التبديل قبل الانقطاع).
  • في بداية كل اختبار، امحِ ذاكرة APF.
  • تثبيت برامج APF أو إعادة تثبيتها كل 5 دقائق أثناء الاختبار

سيناريوهات الاختبار

يجب أن يكون إطار عمل Android Performance Framework نشطًا طوال اختبارات الدمج. يتضمّن هذا المستند برنامجان من "برامج شركاء التطبيقات" يمكن تثبيتهما أثناء الاختبار. تكون البرامج بتنسيق سلسلة سداسية عشرية، وعلى المختبِر تحويل السلسلة السداسية العشرية إلى سلسلة ثنائية وتثبيتها في البرامج الثابتة حتى يتمكن apf_interpreter من تنفيذ البرامج. أثناء اختبار الدمج، يجب أن يرسل المختبِر حِزمًا من المتوقّع أن تؤدي إلى تشغيل منطق الفلترة في البرنامج 1 والبرنامج 2.

APF program 1

عندما تكون شاشة الجهاز مفعّلة، ثبِّت البرنامج 1 من "إطار عمل Android للطباعة". يمكن لهذا البرنامج إسقاط حِزم غير ضارة لا تؤثر في وظائف الجهاز. تُستخدَم هذه الحِزم لاختبار ما إذا كانت ميزة "تصفية حِزم التطبيقات" تعمل على فلترة زيارات الشبكة بشكلٍ صحيح.

في ما يلي منطق البرنامج 1 في "برنامج شركاء Google Play":

  1. إسقاط العداد وزيادته:
    1. قيم EtherType: 0x88A2 و0x88A4 و0x88B8 و0x88CD و0x88E1 و0x88E3
    2. حِزم طلب أو رصد بروتوكول DHCP لبروتوكول IPv4
    3. حِزم RS
  2. النجاح في اختبار عدّاد الزيادة: جميع الحِزم الأخرى

رموز بايت واحد لبرنامج APF هي كما يلي:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
برنامج APF 2

عندما تكون شاشة الجهاز مطفأة، ثبِّت برنامج APF 2. يعمل هذا البرنامج على فلترة جميع الحِزم التي يفلترها برنامج APF‏ 1، بالإضافة إلى حِزم طلبات اختبار الاتصال. للتحقّق من تثبيت برنامج APF 2 بشكل صحيح، أرسِل حِزم ping إلى الجهاز قيد الاختبار.

في ما يلي منطق برنامج APF 2:

  1. إسقاط العداد وزيادته:
    1. قيم EtherType: 0x88A2 و0x88A4 و0x88B8 و0x88CD و0x88E1 و0x88E3
    2. حِزم طلب أو رصد بروتوكول DHCP لبروتوكول IPv4
    3. حِزم RS
  2. إسقاط العداد وزيادته: حِزم طلبات ping ICMP
  3. النجاح في الاختبار وزيادة العداد: جميع الحِزم الأخرى

في ما يلي رموز برنامج 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]

الكود الزائف للبرنامج 1 والبرنامج 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