فیلتر بسته Android

«فیلتر بسته Android» (APF) به چارچوب اجازه می‌دهد منطق فیلتر کردن بسته سخت‌افزار را در زمان اجرا کنترل کند. این کار به سیستم امکان می‌دهد با حذف بسته‌ها در سخت‌افزار، در مصرف انرژی صرفه‌جویی کند و درعین‌حال به چارچوب Android اجازه می‌دهد قوانین فیلتر کردن را در زمان اجرا براساس شرایط شبکه تغییر دهد.

نمای کلی APF

«فهرست مجاز آگهی‌دهندگان» از دو بخش اصلی تشکیل شده است:

  • مفسر APF روی سخت‌افزار شبکه (معمولاً تراشه Wi-Fi) اجرا می‌شود. مفسر APF کدبایت APF را روی بسته‌های دریافتی توسط سخت‌افزار اجرا می‌کند و تصمیم می‌گیرد که آن‌ها را بپذیرد، رها کند، یا به آن‌ها پاسخ دهد.
  • کد تولید برنامه APF در CPU اصلی اجرا می‌شود. این کد برنامه‌های APF را براساس وضعیت شبکه و دستگاه ایجاد و به‌روزرسانی می‌کند.

روش‌های Wi-Fi HAL به چارچوب Android اجازه می‌دهد تا کدبایت برنامه APF را نصب کند و شمارنده‌های فعلی را بخواند. واحد اصلی پشته شبکه می‌تواند کدبایت برنامه 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

میاناهای برنامه‌سازی کاربردی 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 این دو API را درطول منطق انتقال بسته فراخوانی می‌کند. دستورالعمل‌های APF طول متغیری دارند. طول هر دستورالعمل حداقل ۱ بایت است. کدهای دستورالعمل APF در apf.h برای APFv4 تعریف شده‌اند و مستقیماً در apf_interpreter.c برای APFv6 درون‌خطی شده‌اند.

APF به حافظه اختصاصی متکی است. این حافظه هم برای خود برنامه APF و هم برای ذخیره داده‌ها استفاده می‌شود، و حافظه نباید توسط چیپ‌ست پاک یا نوشته شود، مگر ازطریق روش‌های APF HAL. کد بایت APF از فضای ذخیره‌سازی داده برای ذخیره کردن شمارنده‌های بسته‌های پذیرفته‌شده و حذف‌شده استفاده می‌کند. می‌توانید منطقه داده را از چارچوب Android بخوانید. دستورالعمل‌های APF ازنظر حافظه کارآمد هستند، اما به‌حداکثر رساندن پتانسیل صرفه‌جویی در مصرف برق و عملکرد آن‌ها نیازمند قوانین فیلتر کردن پیچیده و پویا است. این پیچیدگی نیازمند بخشی اختصاصی از حافظه روی تراشه است. حداقل حافظه موردنیاز برای APFv4‏ ۱۰۲۴ بایت است، درحالی‌که APFv6 به ۲۰۴۸ بایت نیاز دارد. بااین‌حال، اکیداً توصیه می‌کنیم برای تأیید عملکرد بهینه، ۴۰۹۶ بایت برای APFv6 اختصاص دهید. مترجم APF باید در سفت‌افزار کامپایل شود. هر دو مفسر APFv4 و APFv6 برای اندازه کد بهینه‌سازی شده‌اند. در معماری arm32، مفسر APFv4 تدوین‌شده حدود ۱٫۸ کیلوبایت است، درحالی‌که مفسر APFv6 پیچیده‌تر، با ویژگی‌های اضافه (برای مثال، پشتیبانی از مجموع وارسی داخلی و کد فشرده‌سازی داخلی DNS)، تقریباً ۴ کیلوبایت است.

فیلترهای 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 (نسخه ۴) پشتیبانی می‌کنند.
  • 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 استفاده کنید. ازآنجایی‌که هر شمارنده ۴ بایت طول دارد، مناطق داده باید به‌اندازه کافی طولانی باشند تا مطمئن شویم سرریز بافر رخ نمی‌دهد.

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 باید فقط در سفت‌افزار پیاده‌سازی شود، نه در کد درایور. درغیراین‌صورت، هیچ مزیت صرفه‌جویی در مصرف انرژی وجود ندارد زیرا واحد پردازش مرکزی باید برای پردازش بسته بیدار شود.
  • مقادیر filter_age یا filter_age_16384th نادرست است: مقادیر filter_age (APFv4) و filter_age_16384th (APFv6) باید به‌درستی به تابع‌های accept_packet() و apf_run() منتقل شوند. برای جزئیات مربوط به محاسبه filter_age_16384th، به اسناد موجود در apf_interpreter.h مراجعه کنید.
  • ‫APF درصورت نیاز فعال نیست: وقتی صفحه‌نمایش خاموش است و پیوند Wi-Fi بیکار است یا ترافیک کمتر از ۱۰ مگابیت در ثانیه است، APF باید فعال باشد.
  • بسته‌های ناقص به 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 استفاده می‌کند. تأیید می‌کند که:
    • وقتی صفحه‌نمایش خاموش است و ترافیک Wi-Fi کمتر از ۱۰ مگابیت در ثانیه است، «حالت آماده‌به‌کار برنامه» روشن می‌شود.
    • قابلیت‌های APF به‌درستی اعلام شده باشد.
    • عملیات خواندن و نوشتن در ناحیه حافظه APF موفقیت‌آمیز است و ناحیه حافظه به‌طور غیرمنتظره اصلاح نمی‌شود.
    • متغیرهای مستقل به‌درستی به accept_packet() یا apf_run() ارسال می‌شوند.
    • میان‌افزار یکپارچه‌شده با APFv4/APFv6 می‌تواند بسته‌ها را حذف کند.
    • سفت‌افزار ادغام‌شده با APFv6 می‌تواند به بسته‌ها پاسخ دهد.
  • مجموعه آزمون سازگاری چنددستگاهی APF: از دو دستگاه (یک فرستنده، یک گیرنده) برای آزمایش رفتار فیلتر APF استفاده می‌کند. انواع مختلفی از بسته‌ها در طرف فرستنده تولید می‌شود و آزمایش تأیید می‌کند که آیا براساس قوانین پیکربندی‌شده در ApfFilter به‌درستی حذف، ارسال، یا پاسخ داده می‌شوند یا نه تا عملکرد صحیح APF را تأیید کند.

دستورالعمل‌های اضافی برای آزمایش یکپارچه‌سازی

علاوه‌براین، اکیداً توصیه می‌کنیم که آزمایش APF را در مجموعه‌های آزمایش یکپارچه‌سازی Wi-Fi میان‌افزار خود بگنجانید.

ادغام آزمایش APF در مجموعه‌های آزمایشی ادغام Wi-Fi میان‌افزار برای تأیید عملکرد صحیح APF در سناریوهای پیچیده اتصال Wi-Fi مانند سناریوهای اتصال Wi-Fi «اتصال قبل‌از قطع» یا «گردش» بسیار مهم است. دستورالعمل‌های دقیق درباره نحوه انجام آزمایش‌های یکپارچه‌سازی را می‌توانید در بخش زیر پیدا کنید.

پیش‌نیازها

هنگام انجام آزمایش‌های ادغام، موارد زیر را انجام دهید:

  • «پلتفرم تبلیغات برنامه‌ای» باید در تمام موارد آزمون یکپارچه‌سازی (برای مثال، گردشگری، ساختن-قبل‌از-شکستن) فعال باشد.
  • در شروع هر آزمایش، حافظه APF را پاک کنید.
  • برنامه‌های APF را هر ۵ دقیقه یک‌بار درطول آزمایش نصب یا بازنصب کنید.

سناریوهای آزمایش

«فیلتر درخواست تبلیغات» باید درطول آزمایش‌های یکپارچه‌سازی فعال باشد. این سند دو برنامه APF را ارائه می‌دهد که می‌توانید درطول آزمایش نصب کنید. برنامه‌ها در قالب رشته هگز هستند و باید رشته هگز را به باینری تبدیل کنید و برنامه‌ها را در سفت‌افزار نصب کنید تا apf_interpreter بتواند آن‌ها را اجرا کند. درطول آزمایش یکپارچه‌سازی، باید بسته‌هایی را ارسال کنید که انتظار می‌رود منطق فیلتر کردن را در برنامه ۱ و برنامه ۲ راه‌اندازی کنند.

برنامه APF‏ ۱

وقتی صفحه‌نمایش دستگاه روشن است، برنامه APF 1 را نصب کنید. این برنامه می‌تواند بسته‌های بی‌ضرر را که بر عملکرد دستگاه تأثیر نمی‌گذارند حذف کند. از این بسته‌ها برای آزمایش اینکه آیا APF ترافیک شبکه را به‌درستی فیلتر می‌کند یا نه استفاده می‌شود.

منطق برنامه APF 1 به شرح زیر است:

  1. شمارشگر را رها کنید و افزایش دهید:
    1. مقادیر EtherType: 0x88A2، 0x88A4، 0x88B8، 0x88CD، 0x88E1، 0x88E3
    2. بسته‌های درخواست یا کشف قرارداد پیکربندی میزبان پویا IPv4
    3. بسته‌های RS
  2. گذر و افزایش شمارنده: همه بسته‌های دیگر.

کدهای ۱ بایتی برنامه APF به‌صورت زیر است:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
برنامه APF‏ ۲

وقتی صفحه‌نمایش دستگاه خاموش است، برنامه APF 2 را نصب کنید. این برنامه همه بسته‌هایی را که برنامه APF 1 فیلتر می‌کند، و همچنین بسته‌های درخواست پینگ را فیلتر می‌کند. برای تأیید اینکه برنامه APF 2 به‌درستی نصب شده است، بسته‌های پینگ را به دستگاه تحت آزمایش ارسال کنید.

منطق برنامه APF 2 به شرح زیر است:

  1. شمارشگر را رها کنید و افزایش دهید:
    1. مقادیر EtherType: 0x88A2، 0x88A4، 0x88B8، 0x88CD، 0x88E1، 0x88E3
    2. بسته‌های درخواست یا کشف قرارداد پیکربندی میزبان پویا IPv4
    3. بسته‌های RS
  2. رها کردن و افزایش شمارنده: بسته‌های درخواست پینگ ICMP
  3. گذراندن و افزایش شمارنده: همه بسته‌های دیگر

کدهای ۲ بایتی برنامه APF به‌صورت زیر است:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
درستی‌سنجی داده‌ها

برای تأیید اینکه برنامه APF بسته‌ها را به‌درستی اجرا می‌کند و آن‌ها را ارسال یا حذف می‌کند، کارهای زیر را انجام دهید:

  • منطقه داده APF را هر ۵ دقیقه واکشی و درستی‌سنجی کنید.
  • پیشخوان را پاک نکنید.
  • بسته‌های آزمایشی برای راه‌اندازی هر قانون فیلتر ایجاد کنید.
  • افزایش شمارنده را بااستفاده از این مکان‌های حافظه درستی‌سنجی کنید:

    نام شمارشگر مکان حافظه
    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