xdpdump(8) a simple tcpdump like tool for capturing packets at the XDP layer xdpdump(8)

xdpdump - ابزاری ساده شبیه به tcpdump برای ضبط بسته‌ها در لایه XDP

ابزار xdpdump یک ابزار ساده برای ضبط بسته‌های XDP است که تلاش می‌کند رفتاری شبیه به tcpdump داشته باشد؛ با این حال، فاقد قابلیت‌های فیلتر کردن یا رمزگشایی بسته‌ها است.

از این ابزار می‌توان برای اشکال‌زدایی برنامه‌های XDP که از پیش روی یک رابط شبکه بارگذاری شده‌اند استفاده کرد. بسته‌ها را می‌توان پیش از ورود در بخش entry به برنامه XDP، یا پس از آن هنگام خروج در exit از برنامه XDP تخلیه و بازرسی نمود. افزون بر این، در زمان exit اقدام (action) مربوط به XDP نیز ضبط می‌شود. این بدان معناست که حتی بسته‌هایی که در لایه XDP دور ریخته می‌شوند (dropped) را می‌توان از طریق این ابزار ضبط کرد.

نحوه کارکرد xdpdump به این صورت است که یک برنامه ردیابی bpf را به تابع ورود (entry) و/یا خروج (exit) برنامه XDP متصل می‌کند که بسته خام را در یک بافر ردیابی perf ذخیره می‌نماید. اگر هیچ برنامه XDP بارگذاری نشده باشد، این روش قابل استفاده نخواهد بود و ابزار جهت سازگاری رو به عقب از ضبط زنده با libpcap استفاده خواهد کرد.

نحو اجرای xdpdump به صورت زیر است:

Usage: xdpdump [options]
 XDPDump tool to dump network traffic
Options:
     --rx-capture <mode>    Capture point for the rx direction (valid values: entry,exit)
 -D, --list-interfaces      Print the list of available interfaces
 -i, --interface <ifname>   Name of interface to capture on
     --perf-wakeup <events>  Wake up xdpdump every <events> packets
 -p, --program-names <prog>  Specific program to attach to
 -s, --snapshot-length <snaplen>  Minimum bytes of packet to capture
     --use-pcap             Use legacy pcap format for XDP traces
 -w, --write <file>         Write raw packets to pcap file
 -x, --hex                  Print the full packet in hex
 -v, --verbose              Enable verbose logging (-vv: more verbose)
     --version              Display version information
 -h, --help                 Show this help

ابزار xdpdump تلاش می‌کند گزینه‌های پایه‌ای tcpdump را شبیه‌سازی کند، اما برای اطمینان در ادامه هر یک از گزینه‌های موجود شرح داده شده است:

مشخص می‌کند که بسته ورودی (ingress) در کجا ضبط شود: در ورودی برنامه XDP و/یا در خروجی برنامه XDP. گزینه‌های معتبر عبارتند از entry، exit یا هر دو به صورت entry,exit. بسته در مرحله exit می‌تواند توسط برنامه XDP تغییر یافته باشد. اگر مایلید هم بسته اصلی و هم بسته تغییریافته را ببینید، از گزینه entry,exit استفاده کنید. در این حالت، هر بسته دو بار ضبط خواهد شد. مقدار پیش‌فرض برای این گزینه entry است.

نمایش فهرستی از رابط‌های موجود و هر برنامه XDP بارگذاری‌شده روی آن‌ها.

مشخص می‌کند کدام حالت بارگذار با گزینه --load-xdp-program استفاده شود. مقادیر معتبر عبارتند از: «native» که حالت پیش‌فرض XDP درون درایور است؛ «skb» که باعث استفاده از به اصطلاح حالت skb (همچنین شناخته‌شده به عنوان XDP عمومی یا generic) می‌شود؛ «hw» که باعث برون‌سپاری برنامه به سخت‌افزار می‌گردد؛ یا «unspecified» که انتخاب حالت را به عهده کرنل می‌گذارد (کرنل در صورت پشتیبانی درایور حالت native و در غیر این صورت حالت generic را انتخاب خواهد کرد). توجه داشته باشید که استفاده از «unspecified» پیش‌بینی حالت بارگذاری نهایی برنامه را دشوار می‌کند. به همین دلیل، مقدار پیش‌فرض «native» است.

اگر هیچ برنامه XDP روی رابط شبکه بارگذاری نشده باشد، به‌طور پیش‌فرض xdpdump برای ضبط بسته‌ها به حالت ضبط زنده libpcap بازمی‌گردد. در عوض، با استفاده از این گزینه می‌توانید از xdpdump بخواهید یک برنامه XDP بارگذاری کند تا بسته‌ها را مستقیماً ضبط نماید.

گوش دادن روی رابط شبکه ifname. توجه داشته باشید که اگر هیچ برنامه XDP روی رابط شبکه بارگذاری نشده باشد، برای ضبط بسته‌ها از حالت ضبط زنده libpcap استفاده خواهد شد.

به کرنل اجازه می‌دهد تا به ازای هر <events> رویدادی که در بافر حلقه‌ای perf ثبت می‌شود، یک‌بار xdpdump را بیدار کند. هرچه این عدد بزرگ‌تر باشد، تأثیر آن بر برنامه واقعی XDP کمتر خواهد بود. مقدار پیش‌فرض 0 است که مقدار را به صورت خودکار بر اساس پردازنده‌ها/بافرهای در دسترس محاسبه می‌کند. برای مشاهده مقدار واقعی استفاده‌شده از گزینه -v استفاده کنید.

این گزینه به شما اجازه می‌دهد بسته‌ها را برای یک برنامه خاص، مجموعه‌ای از برنامه‌ها یا تمام برنامه‌های XDP بارگذاری‌شده روی رابط ضبط کنید. می‌توانید نام‌های واقعی برنامه‌ها یا شناسه‌های (IDs) برنامه‌ها را که با کاما از هم جدا شده‌اند مشخص نمایید. در حالتی که چندین برنامه با نام یکسان متصل شده باشند، باید از شناسه برنامه استفاده کنید. از گزینه -D برای دیدن برنامه‌های بارگذاری‌شده و شناسه‌های آن‌ها استفاده کنید.

علاوه بر این، در صورتی که نام تابع ورودی eBPF متصل‌شده بیش از ۱۵ نویسه باشد، API لینوکس نام کامل آن را ارائه نمی‌دهد. در این حالت xdpdump تلاش می‌کند نام صحیح تابع را از اطلاعات اشکال‌زدایی BTF در دسترس حدس بزند. با این حال، اگر چندین تابع با پیشوند نام یکسان وجود داشته باشند، نمی‌تواند مورد صحیح را انتخاب کند. این ابزار توابع موجود را نمایش می‌دهد و شما می‌توانید تابع صحیح را انتخاب کرده و با این گزینه ارسال کنید. اگر برنامه‌هایی با نام‌های طولانی تکراری دارید، باید شناسه برنامه را نیز همراه با نام کامل مشخص کنید. این کار با افزودن شناسه به انتهای نام با پسوند @<id> انجام‌پذیر است.

این گزینه رابط شبکه را در حالت بی‌قید یا درهم‌ریخته (promiscuous mode) قرار می‌دهد.

ضبط snaplen بایت از یک بسته به جای مقدار پیش‌فرض 262144 بایت.

استفاده از قالب قدیمی pcap برای ردگیری‌های XDP. به‌طور پیش‌فرض از قالب PcapNG استفاده می‌شود تا بتواند متاداده‌های گوناگون را ذخیره کند.

نوشتن بسته‌های خام در یک پرونده pcap به جای چاپ آن‌ها به صورت هگزادسیمال (شانزده‌شانزدهی). اگر file برابر با - باشد، از خروجی استاندارد استفاده می‌شود.

هنگام تخلیه بسته‌ها روی کنسول، محتوای کامل بسته را نیز به صورت هگز چاپ می‌کند.

فعال‌سازی ثبت گزارش اشکال‌زدایی. برای جزئیات بیشتر دو بار مشخص کنید (-vv).

نمایش اطلاعات نسخه xdpdump و خروج.

نمایش خلاصه‌ای از گزینه‌های موجود.

دستور زیر برنامه xdp-filter را روی eth0 بارگذاری می‌کند، اما هیچ‌گونه فیلتر کردنی انجام نمی‌دهد:

# xdp-filter load --mode skb eth0
#
# xdpdump -D
Interface        Prio  Program name      Mode     ID   Tag               Chain actions
--------------------------------------------------------------------------------------
lo                     <No XDP program loaded!>
eth0                   xdp_dispatcher    skb      10651 d51e469e988d81da
 =>              10     xdpfilt_alw_all           10669 0b394f43ab24501c  XDP_PASS

اکنون می‌توانیم xdpdump را امتحان کنیم:

# xdpdump -i eth0 -x
listening on eth0, ingress XDP program ID 10651 func xdp_dispatcher, capture mode entry, capture size 262144 bytes
1584373839.460733895: xdp_dispatcher()@entry: packet size 102 bytes, captured 102 bytes on if_index 2, rx queue 0, id 1
  0x0000:  52 54 00 db 44 b6 52 54 00 34 38 da 08 00 45 48  RT..D.RT.48...EH
  0x0010:  00 58 d7 dd 40 00 40 06 ec c3 c0 a8 7a 01 c0 a8  .X..@.@.....z...
  0x0020:  7a 64 9c de 00 16 0d d5 c6 bc 46 c9 bb 11 80 18  zd........F.....
  0x0030:  01 f5 7b b4 00 00 01 01 08 0a 77 0a 8c b8 40 12  ..{.......w...@.
  0x0040:  cc a6 00 00 00 10 54 ce 6e 20 c3 e7 da 6c 08 42  ......T.n ...l.B
  0x0050:  d6 d9 ee 42 42 f0 82 c9 4f 12 ed 7b 19 ab 22 0d  ...BB...O..{..".
  0x0060:  09 29 a9 ee df 89                                .)....
1584373839.462340808: xdp_dispatcher()@entry: packet size 66 bytes, captured 66 bytes on if_index 2, rx queue 0, id 2
  0x0000:  52 54 00 db 44 b6 52 54 00 34 38 da 08 00 45 48  RT..D.RT.48...EH
  0x0010:  00 34 d7 de 40 00 40 06 ec e6 c0 a8 7a 01 c0 a8  .4..@.@.....z...
  0x0020:  7a 64 9c de 00 16 0d d5 c6 e0 46 c9 bc 85 80 10  zd........F.....
  0x0030:  01 f5 74 0c 00 00 01 01 08 0a 77 0a 8c ba 40 12  ..t.......w...@.
  0x0040:  d2 34                                            .4
^C
2 packets captured
0 packets dropped by perf ring

در زیر دو مثال دیگر برای هدایت پرونده ضبط‌شده به tcpdump یا tshark آمده است:

# xdpdump -i eth0 -w - | tcpdump -r - -n
listening on eth0, ingress XDP program ID 10651 func xdp_dispatcher, capture mode entry, capture size 262144 bytes
reading from file -, link-type EN10MB (Ethernet)
15:55:09.075887 IP 192.168.122.1.40928 > 192.168.122.100.ssh: Flags [P.], seq 3857553815:3857553851, ack 3306438882, win 501, options [nop,nop,TS val 1997449167 ecr 1075234328], length 36
15:55:09.077756 IP 192.168.122.1.40928 > 192.168.122.100.ssh: Flags [.], ack 37, win 501, options [nop,nop,TS val 1997449169 ecr 1075244363], length 0
15:55:09.750230 IP 192.168.122.1.40928 > 192.168.122.100.ssh: Flags [P.], seq 36:72, ack 37, win 501, options [nop,nop,TS val 1997449842 ecr 1075244363], length 36
# xdpdump -i eth0 -w - | tshark -r - -n
listening on eth0, ingress XDP program ID 10651 func xdp_dispatcher, capture mode entry, capture size 262144 bytes
    1   0.000000 192.168.122.1 → 192.168.122.100 SSH 102 Client: Encrypted packet (len=36)
    2   0.000646 192.168.122.1 → 192.168.122.100 TCP 66 40158 → 22 [ACK] Seq=37 Ack=37 Win=1467 Len=0 TSval=1997621571 TSecr=1075416765
    3  12.218164 192.168.122.1 → 192.168.122.100 SSH 102 Client: Encrypted packet (len=36)

یک مثال نهایی برای ضبط برنامه‌های XDP خاص بارگذاری‌شده روی رابط شبکه:

# xdpdump -D
Interface        Prio  Program name      Mode     ID   Tag               Chain actions
--------------------------------------------------------------------------------------
lo                     <No XDP program loaded!>
eth0                   xdp_dispatcher    skb      10558 d51e469e988d81da
 =>              5      xdp_test_prog_w           10576 b5a46c6e9935298c  XDP_PASS
 =>              10     xdp_pass                  10582 3b185187f1855c4c  XDP_PASS
 =>              10     xdp_pass                  10587 3b185187f1855c4c  XDP_PASS

می‌خواهیم بسته‌ها را روی برنامه xdp_dispatcher() و دومین برنامه xdp_pass() مشاهده کنیم:

# xdpdump -i eth0 --rx-capture=entry,exit -p xdp_dispatcher,xdp_pass@10587
  or
# xdpdump -i eth0 --rx-capture=entry,exit -p 10558,10587
listening on eth0, ingress XDP program ID 10558 func xdp_dispatcher, ID 10587 func xdp_pass, capture mode entry/exit, capture size 262144 bytes
1607694215.501287259: xdp_dispatcher()@entry: packet size 102 bytes on if_index 2, rx queue 0, id 1
1607694215.501371504: xdp_pass()@entry: packet size 102 bytes on if_index 2, rx queue 0, id 1
1607694215.501383099: xdp_pass()@exit[PASS]: packet size 102 bytes on if_index 2, rx queue 0, id 1
1607694215.501394709: xdp_dispatcher()@exit[PASS]: packet size 102 bytes on if_index 2, rx queue 0, id 1
^C
4 packets captured
0 packets dropped by perf ring

لطفاً هرگونه اشکال را در گیت‌هاب گزارش دهید: https://github.com/xdp-project/xdp-tools/issues

برنامه xdpdump توسط Eelco Chaudron نوشته شده است.

January 13, 2021 V1.6.3