linux 下的 包过滤器 BPF
来源:互联网 发布:mysql python.tar.gz 编辑:程序博客网 时间:2024/05/29 18:39
一, 导论
BPF(Berkeley Packet Filter)伯克利包过滤器。 是在linux 平台下的一个包过滤器。使用此过滤器可以在socket编程时非常方便的实现各种过滤规则。
首先,要确保从socket中读取的是packet,也就是说是 MAC头+IP头+TCP/UDP头。
关于BPF的相关介绍可以查看英文文档:http://www.gsp.com/cgi-bin/man.cgi?section=4&topic=bpf#1
二, BPF的使用
首先来看一段实际应用中的代码:
int init_packet_capture(struct lib_cap *p){int sock = -1;struct sock_fprog Filter;struct sockaddr_ll sll;// tcpdump -dd ether proto 0x8033struct sock_filter bpf_code [] = {{0x20, 0, 0, 0x0000000c},{0x15, 0, 1, 0x00000033},{0x6, 0, 0, 0x00000200},{0x6, 0, 0, 0x00000000}};if (NULL == p) {return -1;}// init filter settings Filter.len =4;Filter.filter = bpf_code;//set default valuep->ifindex = -1;p->fd = -1;p->buffer = NULL;p->buf_len = 0;if ( (sock = socket(PF_PACKET, SOCK_RAW, htons(ETHERTYPE_SADP))) < 0){return -1;}if ( setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter)) < 0); ....}
以上代码首先定义并初始化了一个bpf过滤器 Filter, 然后将其 SO_ATTACH_FILTER 到了socket 上。
这里用到了两个结构体:sock_fprog和sock_filter:
sock_fprog
struct sock_fprog{ unsigned short len; struct sock_filter *filter;}sock_filter
struct sock_filter{__u16code;/* actual filter code */__8jt;/* jump true */__8jf;/* jump false*/__u32k;/* Generic multiuse field */}
知道以上两个结构体后,整段代码就比较清晰了, 唯一比较费解的是那一串数字!!!
struct sock_filter bpf_code [] = {{0x20, 0, 0, 0x0000000c},{0x15, 0, 1, 0x00000033},{0x6, 0, 0, 0x00000200},{0x6, 0, 0, 0x00000000}};下面将分析这一串数字是如何产生的,以及它的意义。
三, BPFcode 生成方法
在注释中有一段提示 tcpdump -dd ether proto 0x8033。
tcpdump 是linux 中调试网络的一个工具, 实际上tcpdump 就是用利用BPF原理编写的一个工具,所以tcpdump 提供了一个生成bpf code 的一个命令行:
这段数字的意义就是过滤以太网协议中类型是 0x8033的数据包(某某IT公司的产品自定义的一个数据包)。这段数字到底实现了什么功能呢? tcpdump 提供了 -d 选项来阐述这段数字的意义:
分析这段代码可知,
ldh 是高位加载, 即从帧的第12位开始加载进内存,第12位就是去除6位src mac 与 6位 dst mac 的数据报类型字段。
jeq: 如果类型字段是 0x8033 的话就返回 96个字节,如果类型字段不是 0x8033的话就返回 0个字节。
至此就已达到过滤类型为0x8033数据包的目的。
小结:
细心的朋友可能会发现,bpf_code 数组的第三行最后一列 0x00000060 与源代码中的 0x00000020 并不一样!这是因为tcpdump 的默认返回字节是96个字节, 而实际需要抓取512(0x00000200, 16*16*2)个字节的数据。关于这点给tcpdump 指定长度字段-s就可以了:
linux 下的 BPF 是包过滤的利器, 结合tcpdump 工具,能非常快速的实现各种个性化的包过滤需求!
- linux 下的 包过滤器 BPF
- PF_RING使用BPF过滤器
- linux中的bpf封包
- Linux内核笔记 -- BPF
- Linux内核net/bpf模块的bpf_tail_call()尾调用机制
- bpf
- bpf
- BPF自己写过滤包程序
- BPF自己写过滤包程序
- socket中BPF的设置
- Linux 中的 DTrace :BPF 进入 4.9 内核
- Introduction to Seccomp: BPF linux syscall filter
- linux下的依赖包
- ethereal的抓包过滤器
- 探索iptables BPF模块的悲惨历程
- linux 简单的过滤器
- Libpcap BPF(BSD Packet Filter)包过滤机制
- linux下的.run包的制作
- gulp自动化打包(上)
- HDU 2089 不要62(数位DP)
- Java正则表达式——分组与捕获
- hdu5969 最大的位或 二进制
- React Native学习指南
- linux 下的 包过滤器 BPF
- DOCKER 详解
- 解决thinkphp3.2中使用redis报错
- 单词首字母转换大小写
- hdu 5961 传递 2016ACM/CCPC合肥赛区现场赛A
- 三极管开关电路设计详细过程
- 玲珑1046 chess play
- nirsoft,很好的工具库
- codeforces contest 733