فیلتر بسته اندروید

فیلتر بسته‌های اندروید (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) ناخواسته است. اگر سیستم عامل از APFv6 پشتیبانی کند، ApfFilter همچنین قوانینی را برای پاسخ به انواع بسته‌های رایج ایجاد می‌کند که در غیر این صورت نیاز به بیدار شدن CPU برای پاسخ دادن دارند، مانند درخواست‌های ARP و درخواست‌های NS. لیست کامل فیلترها در ApfFilter تعریف شده است.

از آنجا که کد تولید برنامه APF بخشی از ماژول Network Stack است، می‌توانید از به‌روزرسانی‌های ماهانه Mainline برای اضافه کردن فیلترهای جدید و به‌روزرسانی منطق فیلترینگ استفاده کنید.

بازنگری APF

فهرست زیر تاریخچه‌ی ویرایش‌های APF را شرح می‌دهد:

  • APFv6: این نسخه که در اندروید ۱۵ معرفی شد، از فیلترینگ بسته‌ها پشتیبانی می‌کند، شامل شمارنده‌هایی برای اشکال‌زدایی و اندازه‌گیری‌ها است و از انتقال بسته‌ها نیز پشتیبانی می‌کند.
  • APFv4: این نسخه که در اندروید ۱۰ معرفی شد، از فیلترینگ بسته‌ها پشتیبانی می‌کند و شامل شمارنده‌هایی برای اشکال‌زدایی و معیارها است.
  • APFv2: این نسخه که در اندروید ۷ معرفی شد، از فیلترینگ بسته‌ها پشتیبانی می‌کند.

ادغام APF

APIهای APF بین مفسر APF و سخت‌افزار در apf_interpreter.h ( APFv4 ، APFv6 ) تعریف شده‌اند. کد میان‌افزار Wi-Fi، تابع accept_packet() در APFv4 یا apf_run() را در APFv6 فراخوانی می‌کند تا مشخص شود که آیا بسته باید حذف شود (مقدار بازگشتی صفر) یا به پردازنده برنامه (مقدار بازگشتی غیر صفر) منتقل شود. اگر یک بسته نیاز به انتقال داشته باشد، apf_run() نیز مقدار صفر را برمی‌گرداند زیرا نیازی به انتقال بسته آن به پردازنده برنامه نیست. اگر میان‌افزار از APFv6 پشتیبانی می‌کند، باید APIهای apf_allocate_buffer() و apf_transmit_buffer() را پیاده‌سازی کند. مفسر APF این دو API را در طول منطق انتقال بسته فراخوانی می‌کند. دستورالعمل‌های APF طول متغیری دارند. هر دستورالعمل حداقل ۱ بایت طول دارد. کدهای دستورالعمل APF برای APFv4 در apf.h تعریف شده‌اند و برای APFv6 مستقیماً در apf_interpreter.c قرار می‌گیرند.

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

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

برای تأیید عملکرد صحیح فیلتر APF، هنگامی که APF روشن است، بررسی کنید که میان‌افزار (Firmware) به فیلتر APF امکان دسترسی به کل بسته، نه فقط هدر، را می‌دهد.

نمونه‌های برنامه APF

ApfTest و ApfFilterTest حاوی برنامه‌های آزمایشی نمونه‌ای هستند که نحوه‌ی عملکرد هر فیلتر APF را نشان می‌دهند. برای مطالعه‌ی برنامه‌ی تولید شده‌ی واقعی، مورد آزمایشی را طوری تغییر دهید که برنامه را به صورت یک رشته‌ی هگز چاپ کند.

پوشه testdata شامل برنامه‌های نمونه APFv4 برای فیلترهای APF RA است. پوشه samples شامل ابزارهای پایتون است که برنامه‌های تخلیه APFv6 را تولید می‌کنند. برای جزئیات بیشتر، به مستندات موجود در فایل‌های ابزار پایتون مراجعه کنید.

اشکال‌زدایی 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} : این به این معنی است که تراشه‌های وای‌فای از 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 باید فقط در میان‌افزار پیاده‌سازی شود، نه در کد درایور. در غیر این صورت، هیچ مزیتی در صرفه‌جویی در مصرف برق وجود ندارد زیرا CPU برای پردازش بسته باید بیدار شود.
  • مقادیر نادرست filter_age یا filter_age_16384th : مقادیر filter_age (APFv4) و filter_age_16384th (APFv6) باید به درستی به توابع accept_packet() و apf_run() ارسال شوند. برای جزئیات بیشتر در مورد محاسبه filter_age_16384th ، به مستندات موجود در apf_interpreter.h مراجعه کنید.
  • APF در صورت نیاز فعال نیست: APF باید زمانی فعال شود که صفحه نمایش خاموش است و یا لینک Wi-Fi غیرفعال است یا ترافیک کمتر از 10 مگابیت در ثانیه است.
  • بسته‌های ناقص ارسالی به accept_packet() یا apf_run() : تمام بسته‌های تک‌پخشی، پخشی و چندپخشی ارسالی به accept_packet() یا apf_run() باید کامل باشند. ارسال بسته‌های ناقص به APF معتبر نیست.

آزمایش‌های APF

از اندروید ۱۵ به بعد، اندروید مجموعه تست سازگاری تک دستگاهی و چند دستگاهی (CTS) را برای فیلتر APF و ادغام مفسر APF ارائه می‌دهد تا عملکرد صحیح APF را تأیید کند. در اینجا به تفصیل هدف هر تست کیس آمده است:

  • آزمون ادغام ApfFilter و apf_interpreter : تأیید می‌کند که ApfFilter بایت‌کد صحیحی تولید می‌کند و apf_interpreter کد را به درستی اجرا می‌کند تا نتایج مورد انتظار را تولید کند.
  • CTS تک دستگاهی APF : از یک دستگاه واحد برای آزمایش عملکرد APF روی چیپست Wi-Fi استفاده می‌کند. موارد زیر را تأیید می‌کند:
    • APF زمانی فعال می‌شود که صفحه نمایش خاموش باشد و ترافیک وای‌فای کمتر از 10 مگابیت بر ثانیه باشد.
    • قابلیت‌های APF به درستی اعلام شده‌اند.
    • عملیات خواندن و نوشتن در ناحیه حافظه APF با موفقیت انجام می‌شود و ناحیه حافظه به طور غیرمنتظره‌ای تغییر نمی‌کند.
    • آرگومان‌ها به درستی به accept_packet() یا apf_run() ارسال می‌شوند.
    • میان‌افزار یکپارچه‌شده با APFv4/APFv6 می‌تواند بسته‌ها را از کار بیندازد.
    • میان‌افزار یکپارچه‌شده با APFv6 می‌تواند به بسته‌ها پاسخ دهد.
  • CTS چند دستگاهی APF : از دو دستگاه (یک فرستنده، یک گیرنده) برای آزمایش رفتار فیلترینگ APF استفاده می‌کند. انواع مختلفی از بسته‌ها در سمت فرستنده تولید می‌شوند و آزمایش تأیید می‌کند که آیا آنها به درستی حذف، عبور داده شده یا بر اساس قوانین پیکربندی شده در ApfFilter برای تأیید عملکرد صحیح APF، به درستی پاسخ داده شده‌اند یا خیر.

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

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

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

پیش‌نیازها

هنگام انجام تست‌های یکپارچه‌سازی، موارد زیر را انجام دهید:

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

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

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

برنامه APF 1

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

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

  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 ، بسته‌های پینگ را به دستگاه تحت آزمایش ارسال کنید.

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

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

کدهای دو بایتی برنامه APF به شرح زیر هستند:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
تأیید داده‌ها

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

  • هر 5 دقیقه یکبار ناحیه داده APF را دریافت و تأیید کنید.
  • پیشخوان را خالی نکنید.
  • بسته‌های آزمایشی را برای فعال کردن هر قانون فیلتر تولید کنید.
  • با استفاده از این مکان‌های حافظه، افزایش شمارنده را تأیید کنید:

    نام شمارنده محل حافظه
    DROPPED_ETHERTYPE_DENYLISTED [اندازه رم - 20، اندازه رم - 16]
    DROPPED_DHCP_REQUEST_DISCOVERY [اندازه رم - 24، اندازه رم - 20]
    DROPPED_ICMP4_ECHO_REQUEST [اندازه رم - ۲۸، اندازه رم - ۲۴]
    DROPPED_RS [اندازه رم - ۳۲، اندازه رم - ۲۸]
    PASSED_PACKET [اندازه رم - ۳۶، اندازه رم - ۳۲]

شبه‌کد برنامه 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