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 pin 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 2 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 có chấp nhận, loại bỏ hay trả lời các gói đó hay không.
  • Mã tạo chương trình APF chạy trên CPU chính. Mã này 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ị.

Các phương thức Wi-Fi HAL cho phép khung Android cài đặt mã byte 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 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 để loại bỏ các ethertype 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 truy cập phát đa hướng và quảng bá nếu khoá 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ỏ các gói giao thức phân giải địa chỉ (ARP) và phát hiện lân cận (ND) không được yêu cầu. Nếu chương trình cơ sở hỗ trợ APFv6, ApfFilter cũng sẽ tạo các quy tắc để trả lời các loại gói thông thường mà nếu không thì CPU sẽ phải thức để phản hồi, chẳng hạn như truy vấn ARP và truy vấn NS queries. 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ể sử dụng các bản cập nhật Mainline hằng tháng để thêm bộ lọc mới và cập nhật logic lọc.

Bản sửa đổi APF

Danh sách sau đây mô tả nhật ký sửa đổi của APF:

  • APFv6: Ra mắt trong Android 15, phiên bản này hỗ trợ lọc gói, bao gồm các bộ đếm để gỡ lỗi và chỉ số, đồng thời hỗ trợ truyền gói.
  • APFv4: Ra mắt trong Android 10, phiên bản này hỗ trợ lọc gói và bao gồm các bộ đếm để gỡ lỗi và chỉ số.
  • APFv2: Ra mắt trong Android 7, phiên bản này hỗ trợ lọc gói.

Tích hợp APF

Các API APF giữa trình thông dịch APF và phần cứng được xác định trong apf_interpreter.h (APFv4, APFv6). Mã chương trình cơ sở Wi-Fi gọi accept_packet() trong APFv4 hoặc apf_run() trong APFv6 để xác định xem gói có nên bị loại bỏ (giá trị trả về bằng 0) hay được chuyển đến bộ xử lý ứng dụng (giá trị trả về khác 0). Nếu một gói cần được truyền, apf_run() cũng sẽ trả về 0 vì gói đó không cần được chuyển đến bộ xử lý ứng dụng. Nếu chương trình cơ sở hỗ trợ APFv6, thì chương trình cơ sở đó phải triển khai các API apf_allocate_buffer()apf_transmit_buffer(). Trình thông dịch APF gọi 2 API này trong logic truyền gói. Các hướng dẫn APF có độ dài thay đổi. Mỗi hướng dẫn có độ dài ít nhất là 1 byte. Mã hướng dẫn APF được xác định trong apf.h cho APFv4 và được nội tuyến trực tiếp trong apf_interpreter.c cho APFv6.

APF dựa vào bộ nhớ chuyên dụng. Bộ nhớ được dùng cho cả chương trình APF và bộ nhớ lưu trữ dữ liệu, đồng thời bộ nhớ không được chipset xoá hoặc ghi, ngoại trừ thông qua các phương thức APF HAL. Mã byte APF sử dụng bộ nhớ lưu trữ dữ liệu để lưu trữ các bộ đếm cho các gói được chấp nhận và bị loại bỏ. Bạn có thể đọc vùng dữ liệu từ khung Android. Các hướng dẫn APF tiết kiệm bộ nhớ, nhưng việc tối đa hoá tiềm năng tiết kiệm pin và chức năng đòi hỏi các quy tắc lọc phức tạp và linh hoạt. Độ phức tạp này đòi hỏi một phần bộ nhớ chuyên dụng trên chipset. Yêu cầu bộ nhớ tối thiểu cho APFv4 là 1024 byte, trong khi APFv6 yêu cầu 2048 byte. Tuy nhiên, bạn nên phân bổ 4096 byte cho APFv6 để xác minh hiệu suất tối ưu. Trình thông dịch APF phải được biên dịch thành chương trình cơ sở. Cả trình thông dịch APFv4 và APFv6 đều được tối ưu hoá cho kích thước mã. Theo kiến trúc arm32, trình thông dịch APFv4 đã biên dịch có kích thước khoảng 1, 8 KB, trong khi trình thông dịch APFv6 phức tạp hơn, với các tính năng bổ sung (ví dụ: hỗ trợ tổng kiểm tra tích hợp và mã giải nén DNS tích hợp), có kích thước khoảng 4 KB.

Các bộ lọc APF có thể hoạt động cùng với các bộ lọc dành riêng cho nhà cung cấp chipset khác trong chương trình cơ sở. Bạn có thể chọn chạy logic lọc trước hoặc sau quá trình lọc APF. Nếu một gói bị loại bỏ trước khi đến bộ lọc APF, thì bộ lọc APF sẽ không xử lý gói đó.

Để xác minh chức năng bộ lọc APF chính xác, khi APF được bật, hãy xác minh rằng chương trình cơ sở cung cấp cho bộ lọc APF quyền truy cập vào toàn bộ gói, chứ không chỉ tiêu đề.

Mẫu chương trình APF

ApfTestApfFilterTest chứa các chương trình kiểm thử mẫu minh hoạ cách hoạt động của từng bộ lọc APF. Để nghiên cứu chương trình thực tế được tạo, hãy sửa đổi trường hợp kiểm thử để in chương trình dưới dạng chuỗi thập lục phân.

Thư mục testdata chứa các chương trình APFv4 mẫu cho bộ lọc APF RA. Thư mục samples chứa các tiện ích Python tạo các chương trình giảm tải APFv6. Để biết thêm thông tin chi tiết, hãy xem tài liệu trong các tệp tiện ích Python.

Gỡ lỗi APF

Để kiểm tra xem APF có được bật trên thiết bị của bạn hay không, hãy hiển thị chương trình hiện tại, hiển thị các bộ đếm hiện tại và 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ả cho 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à tệp nhị phân chương trình APF được cài đặt mới nhất ở định dạng chuỗi thập lục phân.
  • APF packet counters: Phần này cho biết số lượng gói được APF chuyển hoặc loại bỏ và các lý do cụ thể.

Để giải mã và tháo rời mã thành ngôn ngữ hợp ngữ 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 khi 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. Công cụ apf_run hỗ trợ cả trình thông dịch APFv4 và APFv6.

Sau đây là hướng dẫn sử dụng cho lệnh apf_run. Theo mặc định, lệnh apf_run chạy trong trình thông dịch APFv4. Việc truyền đối số --v6 vào apf_run cho phép lệnh này chạy dựa trên trình thông dịch APFv6. Tất cả các đối số khác có thể được dùng cho cả APFv4 và 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.

Dưới đây là ví dụ về cách truyền một gói vào APF để kiểm tra xem gói đó có thể bị loại bỏ hay được chuyển hay không.

Để cung cấp bản trình bày chuỗi nhị phân thập lục phân của gói thô, hãy sử dụng tuỳ chọn --packet. Để cung cấp chuỗi nhị phân thập lục phân của vùng dữ liệu (dùng để lưu trữ bộ đếm APF), hãy sử dụng tuỳ chọn --data. 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 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 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

Để kiểm thử các khả năng truyền APFv6, hãy sử dụng lệnh apf_run như sau:

$ 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

Khi bạn sử dụng tham số --trace, công cụ apf_run sẽ cung cấp kết quả chi tiết của từng bước trong quá trình thực thi của trình thông dịch, rất hữu ích cho việc gỡ lỗi. Trong ví dụ này, bạn sẽ nhập một gói truy vấn ARP vào chương trình APF. Kết quả cho thấy truy vấn ARP bị loại bỏ, nhưng một gói trả lời được tạo. Thông tin chi tiết về gói được tạo này được trình bày trong phần transmitted packet.

Các vấn đề thường gặp khi tích hợp

Phần này nêu bật một số vấn đề thường gặp trong quá trình tích hợp APF:

  • Xoá vùng dữ liệu không mong muốn: Bộ nhớ APF phải hoàn toàn dành riêng cho APF; chỉ mã trình thông dịch hoặc mã khung (thông qua API HAL) mới được phép sửa đổi vùng bộ nhớ APF.
  • Vấn đề khi cài đặt các chương trình APF có X byte (X <= maxLen): Chương trình cơ sở phải hỗ trợ việc đọc hoặc ghi bất kỳ độ dài chương trình nào lên đến maxLen mà không bị lỗi, gặp sự cố hoặc bị cắt bớt. Các thao tác ghi không được làm thay đổi bất kỳ byte nào giữa XmaxLen.
  • Triển khai APF trong mã trình điều khiển: APF chỉ nên được triển khai trong chương trình cơ sở, không phải mã trình điều khiển. Nếu không, sẽ không có lợi ích tiết kiệm pin vì CPU cần thức để xử lý gói.
  • Giá trị filter_age hoặc filter_age_16384th không chính xác: Các giá trị filter_age (APFv4) và filter_age_16384th (APFv6) phải được truyền chính xác đến các hàm accept_packet()apf_run(). Để biết thông tin chi tiết về cách tính filter_age_16384th, hãy tham khảo tài liệu trong apf_interpreter.h.
  • APF không được bật khi cần: APF phải được bật khi màn hình tắt và đường liên kết Wi-Fi ở trạng thái rảnh hoặc lưu lượng truy cập nhỏ hơn 10 Mbps.
  • Các gói bị cắt bớt được truyền đến accept_packet() hoặc apf_run(): Tất cả các gói đơn hướng, quảng bá và phát đa hướng được truyền đến accept_packet() hoặc apf_run() phải hoàn chỉnh. Việc truyền các gói bị cắt bớt vào APF không hợp lệ.

Kiểm thử APF

Kể từ Android 15, Android cung cấp cả trường hợp kiểm tra Bộ kiểm tra tính tương thích (CTS) cho một thiết bị và nhiều thiết bị để tích hợp bộ lọc APF và trình thông dịch APF nhằm xác minh chức năng APF chính xác. Dưới đây là thông tin chi tiết về mục đích của từng trường hợp kiểm thử:

  • Kiểm thử tích hợp ApfFilter và apf_interpreter: Xác minh rằng ApfFilter tạo mã byte chính xác và apf_interpreter thực thi mã chính xác để tạo ra kết quả dự kiến.
  • CTS APF cho một thiết bị: Sử dụng một thiết bị để kiểm thử chức năng APF trên chipset Wi-Fi. Xác nhận rằng:
    • APF bật khi màn hình tắt và lưu lượng truy cập Wi-Fi nhỏ hơn 10 Mbps.
    • Các tính năng APF được khai báo chính xác.
    • Các thao tác đọc và ghi trên vùng bộ nhớ APF thành công và vùng bộ nhớ không bị sửa đổi ngoài dự kiến.
    • Các đối số được truyền chính xác đến accept_packet() hoặc apf_run().
    • Chương trình cơ sở được tích hợp với APFv4/APFv6 có thể loại bỏ các gói.
    • Chương trình cơ sở được tích hợp với APFv6 có thể trả lời các gói.
  • CTS APF cho nhiều thiết bị: Sử dụng 2 thiết bị (một thiết bị gửi, một thiết bị nhận ) để kiểm thử hành vi lọc của APF. Các loại gói khác nhau được tạo ở phía thiết bị gửi và quá trình kiểm thử xác nhận xem các gói đó có bị loại bỏ, được chuyển hay được trả lời chính xác hay không dựa trên các quy tắc được định cấu hình trong ApfFilter để xác minh chức năng APF chính xác.

Hướng dẫn kiểm thử tích hợp bổ sung

Ngoài ra, bạn nên tích hợp quá trình kiểm thử APF vào các bộ kiểm thử tích hợp Wi-Fi trong chương trình cơ sở.

Việc tích hợp quá trình kiểm thử APF vào các bộ kiểm thử tích hợp Wi-Fi trong chương trình cơ sở là rất quan trọng để xác minh chức năng APF phù hợp trong các tình huống kết nối Wi-Fi phức tạp, chẳng hạn như các tình huống kết nối Wi-Fi chuyển vùng hoặc kết nối trước khi ngắt. Bạn có thể xem hướng dẫn chi tiết về cách thực hiện các bài kiểm thử tích hợp trong phần sau.

Điều kiện tiên quyết

Khi bạn thực hiện các bài kiểm thử tích hợp, hãy làm như sau:

  • APF phải được bật trong tất cả các trường hợp kiểm thử tích hợp (ví dụ: chuyển vùng, kết nối trước khi ngắt).
  • Khi bắt đầu mỗi bài kiểm thử, hãy xoá bộ nhớ APF.
  • Cài đặt hoặc cài đặt lại các chương trình APF 5 phút một lần trong quá trình kiểm thử.

Kịch bản kiểm thử

APF phải hoạt động trong suốt quá trình kiểm thử tích hợp. Tài liệu này cung cấp 2 chương trình APF mà bạn có thể cài đặt trong quá trình kiểm thử. Các chương trình ở định dạng chuỗi thập lục phân và bạn phải chuyển đổi chuỗi thập lục phân thành nhị phân và cài đặt các chương trình vào chương trình cơ sở để apf_interpreter có thể thực thi các chương trình đó. Trong quá trình kiểm thử tích hợp, bạn nên gửi các gói dự kiến sẽ kích hoạt logic lọc trong chương trình 1 và chương trình 2.

Chương trình APF 1

Khi màn hình thiết bị bật, hãy cài đặt chương trình APF 1. Chương trình này có thể loại bỏ các gói vô hại không ảnh hưởng đến chức năng của thiết bị. Các gói này được dùng để kiểm thử xem APF có đang lọc lưu lượng truy cập mạng chính xác hay không.

Logic của chương trình APF 1 như sau:

  1. Loại bỏ và tăng bộ đếm:
    1. Giá trị EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Gói yêu cầu hoặc khám phá DHCP IPv4
    3. Gói RS
  2. Chuyển và tăng bộ đếm: Tất cả các gói khác.

Mã byte của chương trình APF 1 như sau:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
Chương trình APF 2

Khi màn hình thiết bị tắt, hãy cài đặt chương trình APF 2. Chương trình này lọc tất cả các gói mà chương trình APF 1 lọc, cũng như các gói yêu cầu ping. Để xác minh rằng chương trình APF 2 được cài đặt chính xác, hãy gửi các gói ping đến thiết bị đang kiểm thử.

Logic của chương trình APF 2 như sau:

  1. Loại bỏ và tăng bộ đếm:
    1. Giá trị EtherType: 0x88A2, 0x88A4, 0x88B8, 0x88CD, 0x88E1, 0x88E3
    2. Gói yêu cầu hoặc khám phá DHCP IPv4
    3. Gói RS
  2. Loại bỏ và tăng bộ đếm: Gói yêu cầu ping ICMP
  3. Chuyển và tăng bộ đếm: Tất cả các gói khác

Mã byte của chương trình APF 2 như sau:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
Xác minh dữ liệu

Để xác minh rằng chương trình APF thực thi và chuyển hoặc loại bỏ các gói chính xác, hãy làm như sau:

  • Tìm nạp và xác minh vùng dữ liệu APF 5 phút một lần.
  • Không xoá bộ đếm.
  • Tạo các gói kiểm thử để kích hoạt từng quy tắc lọc.
  • Xác minh các mức tăng bộ đếm bằng các vị trí bộ nhớ sau:

    Tên bộ đếm Vị trí bộ nhớ
    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]

Mã giả cho chương trình APF 1 và chương trình APF 2

Mã giả sau đây giải thích chi tiết logic của chương trình APF 1 và chương trình 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