.\" netsniff-ng - the packet sniffing beast .\" Copyright 2013 Daniel Borkmann. .\" Subject to the GPL, version 2. .TH BPFC 8 "03 March 2013" "Linux" "netsniff-ng toolkit" .SH "نام (NAME)" bpfc \- یک اسمبلر و کامپایلر فیلتر بسته برکلی (Berkeley Packet Filter) .PP .SH "خلاصه دستور (SYNOPSIS)" .PP \fBbpfc\fP { [\fIگزینه‌ها\fP] | [\fIپرونده-منبع\fP] } .PP .SH "توضیحات (DESCRIPTION)" .PP برنامه bpfc یک اسمبلر و کامپایلر کوچک برای فیلتر بسته برکلی (Berkeley Packet Filter یا BPF) است که قادر است نمادهای یادافزا (mnemonics) شبیه به اسمبلی BPF را به قالبی عددی یا مشابه زبان C ترجمه کند، به گونه‌ای که توسط ابزارهایی مانند netsniff-ng، iptables (xt_bpf) و بسیاری دیگر قابل خواندن باشد. فیلتر BPF تنها ساختار پالایش بالادستی (upstream) است که در ترکیب با سوکت‌های .BR packet (7) و همچنین seccomp-BPF برای سندباکس کردن فراخوانی‌های سیستمی استفاده می‌شود. .PP هسته لینوکس و هسته‌های BSD ساختارهایی شبیه به "ماشین مجازی" و کامپایلرهای JIT را پیاده‌سازی می‌کنند که یک ماشین مبتنی بر ثبات کوچک را در معماری BPF شبیه‌سازی کرده و کد فیلتری را که برای مثال توسط bpfc تولید شده، بر روی یک بافر داده از بسته‌های شبکه اجرا می‌کنند. هدف از این کار انتقال زمانی محاسبات است تا هسته بتواند بسته‌های ورودی را در زودترین زمان ممکن دور بیندازد یا کوتاه کند (truncate)، بدون آنکه نیاز باشد ابتدا آن‌ها را برای بررسی بیشتر به فضای کاربری ارسال کند. در این میان، ساختارهای BPF در زمینه‌های دیگری نظیر ارتباط میان فضای کاربری و فضای هسته مانند سندباکس کردن فراخوانی‌های سیستمی نیز کاربرد پیدا کرده‌اند. .PP در زمان نگارش این صفحه راهنما، تنها کامپایلر دیگر موجود برای BPF بخشی از کتابخانه .BR pcap (3) است که از طریق یک زبان فیلتر سطح بالا که ممکن است برای بسیاری از افراد به عنوان فیلترهای شبیه به tcpdump آشنا باشد، در دسترس است. .PP با این وجود، در موارد متعددی بسیار سودمند است که آن کامپایلر دور زده شود و کدهای بهینه‌سازی‌شده‌ای نوشته شوند که توسط کامپایلر .BR pcap (3) قابل تولید نیستند، یا به اشتباه بهینه‌سازی شده‌اند، یا عمداً به منظور اشکال‌زدایی و آزمودن کد هسته معیوب نوشته شده‌اند. همچنین دلیل دیگر برای استفاده از bpfc می‌تواند آزمودن برخی افزونه‌های جدید BPF باشد که توسط سایر کامپایلرها پشتیبانی نمی‌شوند. افزون بر این، bpfc می‌تواند برای بررسی صحت رفتار کامپایلر JIT یا یافتن اشکالات احتمالی که نیاز به رفع دارند، مفید باشد. .PP برنامه bpfc با کمک .BR flex (1) و .BR bison (1) پیاده‌سازی شده است؛ در مرحله نخست پرونده منبع را نشانه‌گذاری (tokenize) کرده و محتوای آن را به یک درخت نحو انتزاعی (AST) تجزیه می‌کند. سپس در دو مرحله تولید کد، کدهای عملیاتی (opcodes) هدف را صادر می‌نماید. علاوه بر این، bpfc از افزونه‌های BPF هسته لینوکس نیز پشتیبانی می‌کند. جزئیات بیشتر در این باره در بخش نحو آمده است. .PP کامپایلر BPF JIT هسته لینوکس در صورت شناسایی توسط netsniff-ng به طور خودکار فعال می‌شود. با این حال، می‌توان آن را به صورت دستی با دستور ''echo "1" > /proc/sys/net/core/bpf_jit_enable'' (حالت کاری عادی) یا ''echo "2" > /proc/sys/net/core/bpf_jit_enable'' (حالت اشکال‌زدایی که در آن کدهای عملیاتی صادر شده از ایمیج در گزارش وقایع هسته چاپ می‌شوند) نیز فعال کرد. یک دی‌اسمبلر مستقل از معماری برای ایمیج BPF JIT را می‌توان در درخت منبع هسته تحت مسیر ''tools/net/bpf_jit_disasm.c'' یا در مخزن گیت netsniff-ng یافت. .PP .SH "گزینه‌ها (OPTIONS)" .TP .B -i , --input خواندن دستورالعمل‌های اسمبلی BPF از یک پرونده ورودی یا از ورودی استاندارد (stdin). .TP .B -p, --cpp عبور دادن برنامه bpf از پیش‌پردازنده C پیش از خواندن آن در bpfc. این کار امکان استفاده از دستورات هدایت‌کننده #define و #include (به عنوان مثال جهت گنجاندن تعاریف از هدرهای سیستمی) را در برنامه bpf فراهم می‌کند. .TP .B -D =, --define = افزودن تعریف ماکرو برای پیش‌پردازنده C جهت استفاده در پرونده bpf. این گزینه در ترکیب با گزینه \fB-p\fP/\fB--cpp\fP به کار می‌رود. .TP .B -f , --format تعیین قالب خروجی متفاوت با حالت پیش‌فرض سازگار با netsniff-ng. مشخص‌کننده می‌تواند یکی از موارد C، netsniff-ng، xt_bpf یا tcpdump باشد. .TP .B -b, --bypass دور زدن اعتبارسنجی پایه‌ای فیلتر هنگام صدور کدهای عملیاتی. این ویژگی می‌تواند برای ایجاد عمدی عبارت‌های BPF نامعتبر جهت تزریق به هسته (مثلاً برای آزمودن اشکالات) مفید باشد. .TP .B -V, --verbose ارائه گزارش مشروح‌تر و نمایش برخی اطلاعات اشکال‌زدایی bpfc. .TP .B -d, --dump تخلیه (dump) تمامی دستورالعمل‌های پشتیبانی‌شده در خروجی استاندارد (stdout). .TP .B -v, --version نمایش اطلاعات نسخه و خروج. .TP .B -h, --help نمایش راهنمای کاربر و خروج. .PP .SH "نحو (SYNTAX)" .PP معماری BPF و به عبارت دیگر ماشین مبتنی بر ثبات آن از عناصر زیر تشکیل شده است: .PP عنصر توضیحات .PP A انباره ۳۲ بیتی (accumulator) X ثبات ۳۲ بیتی X M[] ۱۶ ثبات متفرقه ۳۲ بیتی موسوم به \[lq]حافظه موقت (scratch memory store)\[rq]، با قابلیت آدرس‌دهی از 0 تا 15 .PP برنامه‌ای که توسط bpfc به ''کدهای عملیاتی (opcodes)'' ترجمه می‌شود، آرایه‌ای متشکل از عناصر زیر است: .PP o:16, jt:8, jf:8, k:32 .PP عنصر o یک کد عملیاتی ۱۶ بیتی است که دستورالعمل خاصی در آن کدگذاری شده است؛ jt و jf دو مقصد پرش ۸ بیتی هستند، یکی برای شرط ''درست (true)'' و دیگری برای شرط ''نادرست (false)''. در نهایت، عنصر ۳۲ بیتی k شامل یک آرگومان متفرقه است که بسته به دستورالعمل یا کد عملیاتی مربوطه می‌تواند به روش‌های مختلفی تفسیر شود. .PP مجموعه دستورالعمل‌ها شامل دستورهای بارگذاری (load)، ذخیره‌سازی (store)، انشعاب (branch)، محاسباتی-منطقی (alu)، متفرقه و بازگشت (return) است که در نحو bpfc نیز پیاده‌سازی شده‌اند. این جدول همچنین شامل افزونه‌های اختصاصی خود bpfc است. تمامی عملیات بر پایه ساختارهای داده بدون علامت (unsigned) انجام می‌شوند: .PP دستورالعمل حالت آدرس‌دهی توضیحات .PP ld 1, 2, 3, 4, 10 بارگذاری کلمه (word) در A ldi 4 بارگذاری کلمه در A ldh 1, 2 بارگذاری نیم‌کلمه (half-word) در A ldb 1, 2 بارگذاری بایت در A ldx 3, 4, 5, 10 بارگذاری کلمه در X ldxi 4 بارگذاری کلمه در X ldxb 5 بارگذاری بایت در X .PP st 3 کپی A در []M stx 3 کپی X در []M .PP jmp 6 پرش به برچسب ja 6 پرش به برچسب jeq 7, 8 پرش در صورت k == A jneq 8 پرش در صورت k != A jne 8 پرش در صورت k != A jlt 8 پرش در صورت k < A jle 8 پرش در صورت k <= A jgt 7, 8 پرش در صورت k > A jge 7, 8 پرش در صورت k >= A jset 7, 8 پرش در صورت k & A .PP add 0, 4 A + sub 0, 4 A - mul 0, 4 A * div 0, 4 A / mod 0, 4 A % neg 0, 4 !A and 0, 4 A & or 0, 4 A | xor 0, 4 A ^ lsh 0, 4 A << rsh 0, 4 A >> .PP tax کپی A در X txa کپی X در A .PP ret 4, 9 بازگشت .PP حالت آدرس‌دهی نحو توضیحات .PP 0 x/%x ثبات X 1 [k] مقدار BHW در آفست بایتی k در بسته 2 [x + k] مقدار BHW در آفست X + k در بسته 3 M[k] کلمه در آفست k در []M 4 #k مقدار لفظی (literal) ذخیره‌شده در k 5 4*([k]&0xf) نیم‌بایت پایینی ضربدر ۴ در آفست بایتی k در بسته 6 L برچسب پرش L 7 #k,Lt,Lf پرش به Lt در صورت برقراری شرط، وگرنه پرش به Lf 8 #k,Lt پرش به Lt در صورت برقراری گزاره 9 a/%a انباره A 10 extension افزونه BPF (جدول بعدی را ببینید) .PP افزونه (و نام مستعار) توضیحات .PP #len, len, #pktlen, pktlen طول بسته (skb->len) #pto, pto, #proto, proto فیلد نوع اترنت (skb->protocol) #type, type نوع بسته (**) (skb->pkt_type) #poff, poff آفست شناسایی‌شده شروع بار داده (payload) #ifx, ifx, #ifidx, ifidx شاخص رابط (skb->dev->ifindex) #nla, nla ویژگی Netlink از نوع X با آفست A #nlan, nlan ویژگی تودرتوی Netlink از نوع X با آفست A #mark, mark نشان بسته (skb->mark) #que, que, #queue, queue, #Q, Q شاخص صف کارت شبکه (skb->queue_mapping) #hat, hat, #hatype, hatype نوع سخت‌افزار کارت شبکه (**) (skb->dev->type) #rxh, rxh, #rxhash, rxhash هش دریافت (skb->rxhash) #cpu, cpu پردازنده فعلی (raw_smp_processor_id()) #vlant, vlant, #vlan_tci, vlan_tci مقدار VLAN TCI (vlan_tx_tag_get(skb)) #vlanp, vlanp وجود VLAN (vlan_tx_tag_present(skb)) .PP جزئیات بیشتر افزونه (**) مقدار .PP #type, type 0 - به ما / میزبان (to us / host) 1 - به همه / همگانی (to all / broadcast) 2 - به گروه / چندپخشی (to group / multicast) 3 - به دیگران (حالت دریافت بی‌قید / promiscuous mode) 4 - خروجی از هر نوع .PP #hat, hat, #hatype, hatype 1 - اترنت ۱۰ مگابیت بر ثانیه 8 - پروتکل APPLEtalk 19 - شبکه ATM 24 - پروتکل IEEE 1394 IPv4 - RFC 2734 32 - اینفینی‌باند (InfiniBand) 768 - تونل IPIP 769 - تونل IP6IP6 772 - دستگاه Loopback 778 - پروتکل GRE بر روی IP 783 - پروتکل Linux-IrDA 801 - استاندارد IEEE 802.11 802 - استاندارد IEEE 802.11 + هدر Prism2 803 - استاندارد IEEE 802.11 + هدر radiotap 823 - پروتکل GRE بر روی IP6 824 - Netlink [...] پرونده include/uapi/linux/if_arp.h را ببینید .PP توجه داشته باشید که اکثریت افزونه‌های BPF تنها در لینوکس در دسترس هستند. .PP دو نوع توضیح (کامنت) در پرونده‌های منبع bpfc وجود دارد: .PP 1. توضیحات چندخطی به سبک C: /* متن توضیح در اینجا */ 2. توضیحات تک‌خطی به سبک اسمبلی: ; متن توضیح در اینجا .PP اختصارات به‌کاررفته: .PP BHW: بایت (byte)، نیم‌کلمه (half-word) یا کلمه (word) .PP .SH "مثال‌های کد منبع (SOURCE EXAMPLES)" .PP در این بخش، چند مثال از پرونده‌های منبع bpfc آورده شده است، به عبارت دیگر، چند برنامه فیلتر نمونه کوچک: .TP .B فقط بازگرداندن هدرهای بسته (کوتاه کردن بسته‌ها): .PP ld poff ret a .TP .B فقط مجاز کردن بسته‌های ARP: .PP ldh [12] jne #0x806, drop ret #-1 drop: ret #0 .TP .B فقط مجاز کردن بسته‌های IPv4 TCP: .PP ldh [12] jne #0x800, drop ldb [23] jneq #6, drop ret #-1 drop: ret #0 .TP .B فقط مجاز کردن ترافیک SSH تحت IPv4 TCP: .PP ldh [12] jne #0x800, drop ldb [23] jneq #6, drop ldh [20] jset #0x1fff, drop ldxb 4 * ([14] & 0xf) ldh [x + 14] jeq #0x16, pass ldh [x + 16] jne #0x16, drop pass: ret #-1 drop: ret #0 .TP .B یک فیلتر seccomp-BPF قابل بارگذاری برای x86_64 جهت مجاز کردن مجموعه‌ای مشخص از فراخوانی‌های سیستمی: .PP ld [4] /* offsetof(struct seccomp_data, arch) */ jne #0xc000003e, bad /* AUDIT_ARCH_X86_64 */ ld [0] /* offsetof(struct seccomp_data, nr) */ jeq #15, good /* __NR_rt_sigreturn */ jeq #231, good /* __NR_exit_group */ jeq #60, good /* __NR_exit */ jeq #0, good /* __NR_read */ jeq #1, good /* __NR_write */ jeq #5, good /* __NR_fstat */ jeq #9, good /* __NR_mmap */ jeq #14, good /* __NR_rt_sigprocmask */ jeq #13, good /* __NR_rt_sigaction */ jeq #35, good /* __NR_nanosleep */ bad: ret #0 /* SECCOMP_RET_KILL */ good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ .TP .B مجاز کردن هر نوع VLAN (با شتاب‌دهی سخت‌افزاری): .PP ld vlanp jeq #0, drop ret #-1 drop: ret #0 .TP .B فقط مجاز کردن ترافیک برای VLAN 10 (با شتاب‌دهی سخت‌افزاری): .PP ld vlant jneq #10, drop ret #-1 drop: ret #0 .TP .B بررسی دقیق‌تر برای مثال VLAN بالا: .PP ld vlanp jeq #0, drop ld vlant jneq #10, drop ret #-1 drop: ret #0 .TP .B فیلتر کردن پیام‌های rtnetlink: .PP ldh #proto /* A = skb->protocol */ jneq #0, skip /* بررسی برای NETLINK_ROUTE */ ldb [4] /* A = nlmsg_type */ jneq #0x10, skip /* بررسی type == RTNL_NEWLINK */ ldx #16 /* X = offset(ifinfomsg) */ ldb [x + 4] /* offset(ifi_index) */ jneq #0x3, skip /* بررسی ifindex == 3 */ ld #32 /* A = len(nlmsghdr) + len(ifinfomsg), آفست بار داده */ ldx #16 /* X = IFLA_OPERSTATE */ ld #nla /* A = offset(IFLA_OPERSTATE) */ jeq #0, skip tax ldb [x + 4] /* A = value(IFLA_OPERSTATE) */ jneq #0x6, skip /* بررسی اینکه وضعیت عملیاتی UP باشد */ ret #-1 skip: ret #0 .PP .SH "مثال‌های کاربردی (USAGE EXAMPLES)" .TP .B bpfc fubar کامپایل پرونده منبع ''fubar'' به کدهای عملیاتی BPF. کدهای عملیاتی به خروجی استاندارد هدایت می‌شوند. .TP .B bpfc -f xt_bpf -b -p -i fubar, resp. iptables -A INPUT -m bpf --bytecode "`bpfc -f xt_bpf -i fubar`" -j LOG کامپایل پرونده منبع ''fubar'' به کدهای عملیاتی BPF، دور زدن اعتبارسنجی پایه‌ای فیلتر و صدور کدهای عملیاتی در قالب قابل خواندن برای xt_bpf در netfilter. توجه داشته باشید که پرونده منبع ''fubar'' ابتدا برای جایگزینی‌های متنی به پیش‌پردازنده C فرستاده می‌شود و سپس به کامپایلر bpfc تحویل داده می‌شود. .TP .B cat fubar | bpfc - خواندن دستورالعمل‌های bpfc از ورودی استاندارد و صدور کدهای عملیاتی به خروجی استاندارد. .TP .B bpfc foo > bar && netsniff-ng -f bar ... کامپایل دستورالعمل‌های فیلتر از پرونده foo و هدایت خروجی bpfc به پرونده bar، که سپس می‌تواند توسط .BR netsniff-ng (8) از طریق گزینه \fB-f\fP خوانده شود. .TP .B bpfc -f tcpdump -i fubar خروجی دادن کدهای عملیاتی از پرونده منبع fubar با رفتاری مشابه ''tcpdump \-ddd''. .PP .SH "حق نشر و قوانین (LEGAL)" برنامه bpfc تحت نسخه ۲.۰ از مجوز عمومی همگانی گنو (GNU GPL) منتشر شده است. .PP .SH "تاریخچه (HISTORY)" \fBbpfc\fP در ابتدا توسط Daniel Borkmann برای جعبه‌ابزار netsniff-ng نوشته شد. در حال حاضر توسط Tobias Klauser و Daniel Borkmann نگهداری می‌شود. .PP .SH "همچنین ببینید (SEE ALSO)" .BR netsniff-ng (8), .BR trafgen (8), .BR mausezahn (8), .BR ifpps (8), .BR flowtop (8), .BR astraceroute (8), .BR curvetun (8) .PP .SH "نویسنده (AUTHOR)" این صفحه راهنما توسط Daniel Borkmann نوشته شده است. .PP .SH "اطلاعات پروژه (COLOPHON)" این صفحه بخشی از پروژه جعبه‌ابزار netsniff-ng در لینوکس است. توضیحات مربوط به پروژه و اطلاعات پیرامون گزارش باگ‌ها را می‌توان در http://netsniff-ng.org/ یافت.