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

فیلتر بسته Android (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. لیست کامل فیلترها در ApfFilter تعریف شده است.

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

ادغام APF

API 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