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 pin bằng cách 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 phiên dịch APF chạy trên phần cứng kết nối mạng (thường là chipset Wi-Fi). Trình phiên dịch APF chạy mã byte APF trên các gói mà phần cứng nhận được rồi quyết định xem nên chấp nhận hay bỏ các gói đó.
- Mã tạo chương trình AFP chạy trên CPU chính. Mã này sẽ 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 thức HAL Wi-Fi cho phép khung Android cài đặt mã byte của chương trình APF và đọc các bộ đếm hiện tại. Mô-đun Network Stack Mainline có thể cập nhật mã byte của chương trình APF bất cứ 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 để bỏ qua các ether không được phép, lọc các gói quảng cáo trên bộ định tuyến (RA) qua bộ định tuyến IPv6, lọc lưu lượng truyền phát và truyền đa hướng nếu khoá đa hướng không được giữ lại, bỏ các gói DHU cho các máy chủ lưu trữ khác và bỏ các gói ND phân giải địa chỉ (ARP) và (khám phá lân cận) không mong muốn. 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 bạn có thể cập nhật logic lọc và thêm các bộ lọc mới thông qua bản cập nhật Mainline hằng tháng.
Tích hợp APF
API APF được định nghĩa trong apf_interpreter.h
.
Mã chương trình cơ sở Wi-Fi gọi int accept_packet()
để xác định xem gói nên bị loại bỏ (giá trị trả về bằng 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 là một byte. Mã hướng dẫn APF được định nghĩa trong apf.h
.
APF dựa vào bộ nhớ chuyên dụng. Bộ nhớ này được dùng cho cả chương trình APF và để lưu trữ dữ liệu. Bộ nhớ không được xoá hoặc ghi bộ nhớ trừ phi thông qua các phương thức APF HAL (Lớp trừu tượng phần cứng). Mã byte APF sử dụng bộ nhớ dữ liệu để lưu trữ bộ đếm cho các gói được chấp nhận và bị bỏ. Bạn có thể đọc khu vực lưu trữ dữ liệu qua khung Android. Dung lượng bộ nhớ tối thiểu có sẵn cho AFA phải là 1024 byte.
Gỡ lỗi APF
Để kiểm tra xem APF đã được bật trên thiết bị hay chưa, hãy hiện chương trình hiện tại và cho thấy các bộ đếm hiện tại, hãy chạy lệnh adb shell dumpsys network_stack
. Sau đây là 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
Kết quả của lệnh adb shell dumpsys network_stack
trong ví dụ này bao gồm:
ApfCapabilities{version: 4, maxSize: 4096, format: 1}
: Tức là các chip Wi-Fi hỗ trợ APF (phiên bản 4).Last program
: Phần này là tệp nhị phân của chương trình APF được cài đặt mới nhất ở định dạng chuỗi hex.APF packet counters
: Phần này cho biết số lượng gói mà APF truyền hoặc bỏ qua và các lý do cụ thể.
Để giải mã và phân tách mã thành ngôn ngữ tập hợp 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 có thể 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 khi không có mạng, hãy sử dụng công cụ apf_run
. Để biên dịch tệp nhị phân có thể 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 dữ liệu bằng lệnh apf_run
.
Để cung cấp bản trình bày chuỗi nhị phân hex của gói thô, hãy sử dụng tuỳ chọn --packet
. Để cung cấp chuỗi nhị phân hex của vùng dữ liệu dùng để lưu trữ bộ đếm AFA, hãy sử dụng --data option
. Vì mỗi bộ đếm có độ dài 4 byte, nên các vùng dữ liệu phải đủ dài để đảm bảo không xảy ra tình trạng tràn vùng đệ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 so với tệp pcap do tcpdump lấy, 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