本文主要介绍在Android中对BPF的使用及其解析,参考Android 7.1源码
注:阅读本文需要一定的网络协议基础
参考文章:https://www.freebsd.org/cgi/man.cgi?query=bpf&sektion=4&manpath=FreeBSD+4.7-RELEASE
什么是BPF
伯克利包过滤器(Berkeley Packet Filter,简称BPF),以协议无关的方式提供指向数据链路层的原始接口,网络上的所有数据包都可以通过这种机制进行访问。伯克利包过滤器以一种字符设备存在,如"/dev/bpf0"
,"/dev/bpf1"
等,这些字符设备的文件描述符都通过BIOCSETIF
ioctl与特定的网络接口进行绑定,每一个网络接口都可以和多个绑定的监听者共享,因此每个文件描述符下的过滤器可以看到被过滤出的包。
BPF在Android中的运用
使用BPF过滤报文非常高效,且规则自定义非常强大,tcpdump中就是使用了BPF进行包过滤。在Android中,很早就使用了BPF,典型的一个例子就是DhcpClient,作为dhcp过程的请求方,在发出dhcp request之后,就是通过BPF过滤对应特征的报文来确定是否dhcp成功,同时获取dhcp server分配的IP地址。
/** frameworks/base/services/net/java/android/net/dhcp/DhcpClient.java*/
// - We use a packet socket to receive, because servers send us packets bound for IP addresses
// which we have not yet configured, and the kernel protocol stack drops these.
// - We use a UDP socket to send, so the kernel handles ARP and routing for us (DHCP servers can
// be off-link as well as on-link).
private FileDescriptor mPacketSock;
为什么要使用BPF来实现dhcp这一项功能?上面