מסנן חבילת Android

מסנן Android Packet (APF) מאפשר ללוגיקת סינון חבילות החומרה של framework במהלך זמן ריצה. כך המערכת חוסכת באנרגיה על ידי ביטול חבילות בחומרה, ומאפשרת למסגרת Android לשנות את כללי הסינון בזמן הריצה על סמך תנאי הרשת.

סקירה כללית על APF

APF מורכב משני רכיבים עיקריים:

  • המפרש של APF פועל בחומרת הרשת (בדרך כלל, שבב ה-Wi-Fi). המפרש של APF מפעיל קוד בייט של APF על חבילות שהחומרה מקבלת, ומחליט אם לקבל אותן, להשליך אותן או להשיב להן.
  • קוד היצירה של תוכנית ה-APF פועל ב-CPU הראשי. הקוד יוצר ומעדכן תוכניות APF בהתאם למצב הרשת והמכשיר.

שיטות ה-HAL של Wi-Fi מאפשרות למסגרת Android להתקין את קוד המקור של תוכנית APF ולקרוא את המונים הנוכחיים. המודול Network Stack Mainline יכול לעדכן את קוד הבייט של תוכנית APF בכל שלב בזמן שפועלת APF.

הוטמעו כמה מסנני APF. לדוגמה, APF כולל מסננים להסרת חבילות ethertype אסורות, סינון חבילות פרסום בנתב IPv6 (RA), סינון של תעבורת נתונים בשידורים מרובים ותעבורת נתונים אם נעילת השידורים לא מוחזקת, שחרור חבילות DHCP עבור מארחים אחרים ושחרור של פרוטוקולי רזולוציית כתובות (ARP) לא רצויים ושל חבילות גילוי בסביבה (ND). אם הקושחה תומכת ב-APFv6,‏ ApfFilter יוצר גם כללים לתשובה לסוגים נפוצים של חבילות, שבמקרה אחר ידרשו את הפעלת המעבד כדי להגיב, כמו שאילתות ARP ושאילתות NS. רשימת המסננים המלאה מוגדרת ב-ApfFilter.

מאחר שקוד היצירה של תוכנית ה-APF הוא חלק מהמודול של סטאק הרשת, תוכלו להשתמש בעדכוני Mainline החודשיים כדי להוסיף מסננים חדשים ולעדכן את הלוגיקה של הסינון.

גרסה של APF

הרשימה הבאה מתארת את היסטוריית הגרסאות של APF:

  • APFv6: הגרסה הזו, שהוצגה ב-Android 15, תומכת בסינון חבילות, כוללת ספירות לניפוי באגים ומדדים, ותומכת בהעברת חבילות.
  • APFv4: הגרסה הזו, שהוצגה ב-Android 10, תומכת בסינון חבילות וכוללת ספירות לניפוי באגים ולמדדים.
  • APFv2: הגרסה הושקה ב-Android 7 והיא תומכת בסינון חבילות.

שילוב עם 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 הן באורך משתנה. כל הוראה באורך של 1 בייט לפחות. קודי ההוראות של APF מוגדרים ב-apf.h ל-APFv4, והם מוטמעים ישירות ב-apf_interpreter.c ל-APFv6.

APF מסתמך על זיכרון ייעודי. הזיכרון משמש גם לתוכנית APF עצמה וגם לאחסון נתונים, אסור לערכת השבבים לנקות או לכתוב בזיכרון אלא באמצעות השיטות של APF HAL. קוד הבייט של APF משתמש במאגר הנתונים כדי לאחסן ספירה של חבילות שאושרו ושל חבילות שהוחמצו. אפשר לקרוא את אזור הנתונים מסביבת Android. הוראות APF יעילות בזיכרון, אבל כדי למקסם את הפוטנציאל שלהן לחיסכון באנרגיה ולפונקציונליות נדרשות כללי סינון דינמיים ומורכבים. המורכבות הזו מחייבת חלק ייעודי של זיכרון בתוך הצ'יפסט. דרישת הזיכרון המינימלית ל-APFv4 היא 1,024 בייטים, ואילו ל-APFv6 נדרשים 2,048 בייטים. עם זאת, מומלץ מאוד להקצות 4096 בייטים ל-APFv6 כדי להבטיח ביצועים אופטימליים. המתרגם של APF צריך לעבור קושחה נפרדת. המתרגם של APFv4 ו-APFv6 עברו אופטימיזציה לגודל הקוד. בארכיטקטורה arm32, המהדר של APFv4 המהדר הוא כ-1.8KB, ואילו המהדר המורכב יותר של APFv6, עם תכונות נוספות (למשל, תמיכה בסיכום בוליאני מקורי וקוד דחיסה מקורי של DNS), הוא כ-4KB.

מסנני APF יכולים לפעול לצד מסננים אחרים ספציפיים ליצרן שבב בתוך הקושחה. ספקי שבבים יכולים לבחור להריץ את הלוגיקה של הסינון שלהם לפני או אחרי תהליך הסינון של APF. אם חבילה נופלת לפני שהיא מגיעה למסנן APF, מסנן APF לא מעבד את החבילה.

כדי להבטיח את הפונקציונליות הנכונה של מסנן ה-APF, כש-APF מופעל, הקושחה חייבת לספק למסנן ה-APF גישה לחבילה כולה, ולא רק לכותרת, כש-APF מופעל.

דוגמאות לתוכניות APF

ApfTest ו-ApfFilterTest מכילים תוכניות בדיקה לדוגמה שממחישות את אופן הפעולה של כל מסנן APF. כדי לבחון את התוכנית שנוצרה בפועל, משנים את מקרה הבדיקה כך שהתוכנית תודפס כמחרוזת הקסדצימלית.

התיקייה testdata מכילה תוכניות APFv4 לדוגמה למסנני RA של APF. התיקייה samples מכילה כלי Python שיוצרים תוכניות של העברת עומסים (offload) ב-APFv6. למידע נוסף, עיינו במסמכי העזרה בקובצי השירות של Python.

ניפוי באגים ב-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: הקטע הזה הוא קובץ ה-binary העדכני ביותר של תוכנית 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 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

כדי לבדוק את יכולות השידור של 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 רק בתוך קושחה, ולא בקוד מנהל התקן. אחרת, אין יתרונות לחיסכון באנרגיה כי המעבד צריך לצאת ממצב שינה כדי לעבד את החבילה.
  • ערכים שגויים של 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 לא פעיל או כשהתעבורת הנתונים נמוכה מ-10Mbps.
  • מנות קטועות שהועברו אל accept_packet() או אל apf_run(): כל המנות של שידור unicast, שידור broadcast ושידור multicast שהועברו אל accept_packet() או אל apf_run() חייבות להיות מלאות. אי אפשר להעביר מנות חתוכות ל-APF.

בדיקות APF

החל מ-Android 15, Android מספק מקרי בדיקה של CTS במכשיר יחיד וגם במכשירים מרובים לצורך שילוב של מסנן APF ותרגום של APF, כדי להבטיח שהפונקציונליות של APF תהיה נכונה. פירוט של המטרה של כל תרחיש בדיקה:

  • בדיקת השילוב של ApfFilter ו-apf_interpreter: מוודאת ש-ApfFilter יוצר bytecode תקין ושהקוד של apf_interpreter מופעל בצורה נכונה כדי לייצר את התוצאות הצפויות.
  • CTS של APF במכשיר יחיד: המערכת משתמשת במכשיר יחיד כדי לבדוק את הפונקציונליות של APF בערכת השבבים של ה-Wi-Fi. מאשרת את הדברים הבאים:
    • APF מופעל כשהמסך מופעל וקצב התעבורה ב-Wi-Fi נמוך מ-10Mbps.
    • היכולות של APF מוצהרות בצורה נכונה.
    • פעולות קריאה וכתיבה באזור הזיכרון של APF מצליחות, ואזור הזיכרון לא משתנה באופן בלתי צפוי.
    • הארגומנטים מועברים בצורה נכונה אל accept_packet() או אל apf_run().
    • קושחת שמשולבת עם APFv4/APFv6 עלולה להפיל חבילות.
    • קושחה שמשולבת עם APFv6 יכולה להשיב למנות.
  • APF לכמה מכשירים: ניתן להשתמש בשני מכשירים (שולח אחד, מקלט אחד) כדי לבדוק את התנהגות הסינון של APF. בצד השולח נוצרים סוגים שונים של חבילות, והבדיקה מאשרת אם הן נמחקות, מועברות או מקבלות תשובה בצורה נכונה על סמך הכללים שהוגדרו ב-ApfFilter.

הוראות נוספות לבדיקת אינטגרציה

בנוסף, אנחנו ממליצים מאוד שספקי ערכות שבבים ישלבו בדיקות APF בחבילות בדיקת קושחה של שילוב Wi-Fi.

שילוב של בדיקות APF בחבילות בדיקות של שילוב Wi-Fi בקושחה חיוני לאימות פונקציונליות של APF תקינה בתרחישים מורכבים של חיבור Wi-Fi, כמו תרחישי לפני הפסקה או נדידה של חיבור Wi-Fi. בהמשך מפורטות הוראות לביצוע בדיקות שילוב.

דרישות מוקדמות

כשמבצעים בדיקות שילוב, צריך לבצע את הפעולות הבאות:

  • צריך להפעיל את APF בכל תרחישי בדיקת השילוב (לדוגמה, נדידה, שינוי לפני שבר).
  • בתחילת כל בדיקה, צריך לנקות את הזיכרון של APF.
  • מתקינים או מתקינים מחדש תוכניות APF מדי 5 דקות במהלך הבדיקה.

תרחישים לבדיקה

APF צריך להיות פעיל במהלך בדיקות השילוב. במסמך הזה מפורטות שתי תוכניות APF שאפשר להתקין במהלך הבדיקה. התוכניות נמצאות בפורמט של מחרוזת הקסדצימלי, והבודק צריך להמיר את המחרוזת הקסדצימלי לפורמט בינארי ולהתקין אותה בקושחה כדי שapf_interpreter יוכל להריץ את התוכניות. במהלך בדיקת השילוב, הבודק צריך לשלוח חבילות שצפויות להפעיל את לוגיקת הסינון בתוכנית 1 ובתוכנית 2.

תוכנית APF 1

כשמסך המכשיר מופעל, מתקינים את תוכנית APF 1. התוכנית הזו יכולה להפיל חבילות לא מזיקות שלא משפיעות על הפונקציונליות של המכשיר. החבילות האלה משמשות כדי לבדוק אם APF מסנן בצורה נכונה את תעבורת הנתונים ברשת.

הלוגיקה של תוכנית APF היא כך:

  1. משחררים ומגדילים את המונה:
    1. ערכי EtherType: 0x88A2, ‏ 0x88A4, ‏ 0x88B8, ‏ 0x88CD, ‏ 0x88E1,‏ 0x88E3
    2. חבילות גילוי או בקשה של IPv4 DHCP
    3. חבילות RS
  2. העברה והגדלת המונה: כל שאר החבילות.

קודי ה-byte של תוכנית APF הם:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C005D88A27C005888A47C005388B87C004E88CD7C004988E17C004488E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE8721D120C84000E86DD0A1482093A0A368204856BE072086BDCB03A01B87206B03A01B87201
תוכנית APF 2

כשמסך המכשיר כבוי, מתקינים את תוכנית APF 2. התוכנית מסננת את כל המנות שתוכנית APF 1 מסננת, וגם מנות של בקשות ping. כדי לוודא שתוכנית APF 2 מותקנת בצורה נכונה, שולחים חבילות פינג למכשיר שנבדק.

הלוגיקה של תוכנית APF מס' 2:

  1. משחררים ומגדילים את המונה:
    1. ערכי EtherType: 0x88A2, ‏ 0x88A4, ‏ 0x88B8, ‏ 0x88CD, ‏ 0x88E1,‏ 0x88E3
    2. חבילות גילוי או בקשה של IPv4 DHCP
    3. חבילות RS
  2. הטלת חבילות של בקשות ICMP ping וספירה שלהן
  3. העברה והגדלת המונה: כל שאר החבילות

קודי ה-2 בייטים של תוכנית APF הם:

6BF0B03A01B86BF8AA0FB86BF4AA09B8120C6BEC7C007488A27C006F88A47C006A88B87C006588CD7C006088E17C005B88E3120C84002008001A1A821B001A1E8600000010FFFFFFFF0A17820B11AB0D2A108204436BE87234120C84000E86DD0A1482093A0A368204856BE0721F120C84001008000A17820B01AB0D220E8204086BE472086BDCB03A01B87206B03A01B87201
אימות נתונים

כדי לוודא שתוכנת APF פועלת ושהמנות מועברות או מוסרות בצורה תקינה:

  • אחזור ואימות של אזור הנתונים של APF כל 5 דקות.
  • לא לנקות את המונה.
  • יוצרים חבילות בדיקה כדי להפעיל כל כלל סינון.
  • מאמתים את ההגדלה של המונה באמצעות מיקומי הזיכרון הבאים:

    שם המונה מיקום הזיכרון
    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]

Pseudocode לתוכנית APF ולתוכנית 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