Linux的抓包socket的过滤bpf指令怎么写

June 11, 2020 | 1 Minute Read

在内核源码的 https://elixir.bootlin.com/linux/latest/source/Documentation/networking/filter.txt 文件列出了怎么在程序里面写bpf代码 https://docs.cilium.io/en/latest/bpf/ 对bpf的实现架构也有点说明 “tcpdump ether multicast -dd” 这个也可以用tcpdump直接生成指定bfp表达式的code,然后在程序里面使用这个code数组 ```text SO_ATTACH_FILTER (since Linux 2.2), SO_ATTACH_BPF (since Linux 3.19) Attach a classic BPF (SO_ATTACH_FILTER) or an extended BPF (SO_ATTACH_BPF) program to the socket for use as a filter of incoming packets. A packet will be dropped if the filter pro‐ gram returns zero. If the filter program returns a nonzero value which is less than the packet's data length, the packet will be truncated to the length returned. If the value returned by the filter is greater than or equal to the packet's data length, the packet is allowed to proceed unmodi‐ fied. The argument for SO_ATTACH_FILTER is a sock_fprog structure, defined in : struct sock_fprog { unsigned short len; struct sock_filter *filter; }; The argument for SO_ATTACH_BPF is a file descriptor returned by the bpf(2) system call and must refer to a program of type BPF_PROG_TYPE_SOCKET_FILTER. These options may be set multiple times for a given socket, each time replacing the previous filter program. The classic and extended versions may be called on the same socket, but the previous filter will always be replaced such that a socket never has more than one filter defined. Both classic and extended BPF are explained in the kernel source file Documentation/networking/filter.txt ``` 那些bpf指令宏是在这个头文件定义的 https://elixir.bootlin.com/linux/latest/source/include/uapi/linux/filter.h ```c /* * Macros for filter block array initializers. */ #ifndef BPF_STMT #define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k } #endif #ifndef BPF_JUMP #define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k } #endif ``` jump指令里面jt和jf都是相对地址,跳过几行吧,这里讲的比较清楚 https://blog.csdn.net/u013837209/article/details/54926309 tcpdump ======= tcpdump可以用-dd 或者-d命令生成 表达式的 bpf 指令数组吧, ```text -d Dump the compiled packet-matching code in a human readable form to standard output and stop. -dd Dump packet-matching code as a C program fragment. -ddd Dump packet-matching code as decimal numbers (preceded with a count). ```