9.1.7 BPF指令集实例

下面给出一些实例来解释如何用BPF指令集表示数据包过滤器(在所有的实例中,假设数据链路层的协议头都为以太网的典型帧格式)。

实例1:接收所有的IP数据包。执行命令tcpdump-d ip,获得如下指令:


(000)ldh[12]//加载数据包的协议类型值

(001)jeq#0x800 jt 2 jf 3//检查是否为IP协议

(002)ret#96//返回TRUE

(003)ret#0//返回FALSE


第一条指令加载以太网类型字段,即帧结构除去前导码的第12、13字节。

第二条指令把该类型值与IP类型值(0x800)比较,如果比较失败,执行第四条指令返回0,并丢弃该数据包。

如果比较成功,则执行第三条指令,返回TRUE(TRUE为非0值,表示需要存储数据包的字节数,此处其值为96),同时接收该数据包(或数据包的一部分)。

实例2:接收所有IP数据包或ARP数据包(图9-2中CFG的实现)。执行命令tcpdump-d ip or arp,获得如下指令:


(000)ldh[12]//加载数据包的协议类型值

(001)jeq#0x800 jt 3 jf 2//检查是否为IP协议

(002)jeq#0x806 jt 3 jf 4//检查是否为ARP协议

(003)ret#96//返回TRUE

(004)ret#0//返回FALSE


第一条指令装载以太网数据包封装的上层协议类型值,数据包中的偏移值为12字节。第二条指令会将该值与IP类型值(0x800)进行比较,如果相等,跳转至(003)处返回TRUE并接收该数据包;如果不相等,跳转至(002)处。第三条语句会将数据包的类型值与ARP类型值(0x806)进行比较,如果相等,跳转至(003)处返回TRUE并接收该数据包;否则跳转至(004)处,返回FALSE并丢弃该数据包。