Bộ lọc gói Android

Bộ lọc gói Android (APF) cho phép khung kiểm soát logic lọc gói phần cứng trong thời gian chạy. Điều này cho phép hệ thống tiết kiệm năng lượng bằng cách loại bỏ các gói trong phần cứng, đồng thời cho phép khung Android thay đổi quy tắc lọc trong thời gian chạy dựa trên điều kiện mạng.

Tổng quan về APF

APF bao gồm hai thành phần chính:

  • Trình thông dịch APF chạy trên phần cứng mạng (thường là chipset Wi-Fi). Trình thông dịch APF chạy mã byte APF trên các gói mà phần cứng nhận được và quyết định chấp nhận hay loại bỏ chúng.
  • Mã tạo chương trình APF chạy trên CPU chính. Mã tạo và cập nhật các chương trình APF theo trạng thái mạng và thiết bị.

Phương pháp Wi-Fi HAL cho phép khung Android cài đặt mã byte chương trình APF và đọc bộ đếm hiện tại. Mô-đun Network Stack Mainline có thể cập nhật mã byte chương trình APF bất kỳ lúc nào trong khi APF đang chạy.

Có một số bộ lọc APF được triển khai. Ví dụ: APF bao gồm các bộ lọc để loại bỏ các loại ether không được phép, lọc các gói quảng cáo bộ định tuyến IPv6 (RA), lọc lưu lượng phát đa hướng và phát sóng nếu khóa phát đa hướng không được giữ, loại bỏ các gói DHCP cho các máy chủ khác và loại bỏ giao thức phân giải địa chỉ không được yêu cầu (ARP) và (khám phá lân cận) các gói ND. Danh sách đầy đủ các bộ lọc được xác định trong ApfFilter .

Vì mã tạo chương trình APF là một phần của mô-đun Network Stack nên logic lọc có thể được cập nhật và có thể thêm các bộ lọc mới thông qua các bản cập nhật Mainline hàng tháng.

Tích hợp APF

API APF được xác định trong apf_interpreter.h . Mã chương trình cơ sở Wi-Fi gọi int accept_packet() để xác định xem gói sẽ bị loại bỏ (giá trị trả về 0) hay được chuyển (giá trị trả về khác 0). Hướng dẫn APF có độ dài thay đổi. Mỗi lệnh có độ dài ít nhất một byte. Mã hướng dẫn APF được xác định trong apf.h .

APF dựa vào bộ nhớ chuyên dụng. Bộ nhớ được sử dụng cho cả chương trình APF và để lưu trữ dữ liệu, đồng thời bộ nhớ không được xóa hoặc ghi bởi chipset ngoại trừ thông qua các phương pháp APF HAL. Mã byte APF sử dụng bộ lưu trữ dữ liệu để lưu trữ bộ đếm cho các gói được chấp nhận và bị loại bỏ. Vùng dữ liệu có thể được đọc từ khung Android. Dung lượng bộ nhớ tối thiểu khả dụng cho APF phải là 1024 byte.

Gỡ lỗi APF

Để kiểm tra xem APF có được bật trên thiết bị hay không, hãy hiển thị chương trình hiện tại và hiển thị bộ đếm hiện tại, hãy chạy lệnh adb shell dumpsys network_stack . Sau đây là một ví dụ về lệnh này:

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

Đầu ra của lệnh adb shell dumpsys network_stack trong ví dụ này bao gồm:

  • ApfCapabilities{version: 4, maxSize: 4096, format: 1} : Điều này có nghĩa là chip Wi-Fi hỗ trợ APF (phiên bản 4).
  • Last program : Phần này là chương trình nhị phân APF được cài đặt mới nhất ở định dạng chuỗi hex.
  • APF packet counters : Phần này hiển thị số lượng gói được APF truyền hoặc loại bỏ và các lý do cụ thể.

Để giải mã và phân tách mã thành ngôn ngữ trình biên dịch mã mà con người có thể đọc được, hãy sử dụng công cụ apf_disassembler . Để biên dịch tệp nhị phân thực thi, hãy chạy lệnh m apf_disassembler . Sau đây là ví dụ về cách sử dụng công cụ 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
......

Để kiểm tra kết quả APF ngoại tuyến, hãy sử dụng công cụ apf_run . Để biên dịch tệp nhị phân thực thi, hãy chạy lệnh m apf_run . Sau đây là ví dụ về cách kiểm tra một gói bằng lệnh apf_run .

Để cung cấp cách trình bày chuỗi nhị phân hex của gói thô, hãy sử dụng tùy chọn --packet . Để cung cấp chuỗi nhị phân hex của vùng dữ liệu, được sử dụng để lưu trữ bộ đếm APF , hãy sử dụng --data option . Vì mỗi bộ đếm dài 4 byte nên vùng dữ liệu phải đủ dài để đảm bảo không xảy ra lỗi tràn bộ đệm.

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b9494010c06006b907c010588a27c010088a47c00fb88b87c00f688cd7c00f188e17c00ec88e384003908066a0e6bdca2d40600010800060412147a18016bd882ca021a1c6b8c7ac900686bd4a2b706ffffffffffff6a266bbca2b204c0a814656bf872a8120c84005808000a17821e1112149c00171fffab0d2a108210446a3239a204064651dbcc88ff6bf4727e0a1e52f06bac7a7be06bb41a1e7e0000006effffffff6bb07e00000063c0a814ff6be868a25106ffffffffffff6bb872536bf072497c001086dd686bd0a23806ffffffffffff6bc8723a0a147a0b3a6b980a267a2eff6be072240a366ba87a23858218886a26a2040fff02000000000000000000000000006ba472086be4b03a01b87206b03a01b87201 --packet 5ebcd79a8f0dc244efaab81408060001080006040002c244efaab814c0a8ca1e5ebcd79a8f0d --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Packet passed
Data: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001

Để kiểm tra kết quả APF dựa trên tệp pcap được lấy bởi tcpdump, hãy sử dụng lệnh apf_run như sau:

out/host/linux-x86/bin/apf_run --program 6bfcb03a01b8120c6b989401df06006b947c01d888a27c01d388a47c01ce88b87c01c988cd7c01c488e17c01bf88e384004408066a0e6bdca401a5000600010800060412147a1e016bd884019900021a1c6b907c01960000686bd4a401820006ffffffffffff6a266bc0a4017b0004c0a82b056bf874017084005f08000a17821f1112149c00181fffab0d2a108211446a3239a20506fabe589435936bf47401470a1e52f06bb07c014200e06bb81a1e7e00000135ffffffff6bb47e0000012ac0a82bff6be868a401160006ffffffffffff6bbc7401176bf074010c7c001086dd686bd0a2fb06ffffffffffff6bcc72fd0a147a0b3a6b9c0a267af1ff6be072e70a366bac7ae6858218886a26a2040fff02000000000000000000000000006ba872cbaa0e82be8eaa0f8c00b7025868a2a40ffabe5894359352a9874d08aa86dd606a12a2792600583afffe80000000000000f7d4e8ccd81ddb43fe80000000000000f8be58fffe94359386006a3aa272024108123c94006b02586a3ea25e0800000000000000006a56a25504030440c01a5a94004e02581a5e94004702586a62a23e04000000006a66a229102409891f9a26ae6d00000000000000006a76a22004190300001a7a94001902586a7ea204102409891f9a26ae6dba98e781ca9ef9ba6bc872086be4b03a01b87206b03a01b87201 --pcap apf.pcap --data 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
37 packets dropped
1733 packets passed
Data: 00000000000000000000000000000000000000000200000005000000000000000000000002000000000000001b000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000689000000000000003c00000000000000000000000000000000000006ea