2.1 伯克利包过滤
Wireshark中的数据包过滤指的只显示那些我们感兴趣的数据包。在前面的实例中,我们就曾经利用IP地址将一部分无用的数据包隐藏了起来。但是这种仅仅依靠IP地址来过滤的方法有很大的局限性,下面我们来介绍一种功能更加完善的方法。
1993年,Steven McCanne与Van Jacobson在Usenix'93会议上提出的一种机制——伯克利包过滤(Berkeley Packet Filter,BPF),它采用了一种与我们自然语言很接近的语法,利用这种语法构成的字符串可以确定保留哪些数据包以及忽略掉哪些数据包。
这种语法很容易理解,例如最简单的空字符串,表示就是不过滤任何数据包,也就是保留所有的数据包。如果这个字符串不为空的话,那么只有那些使字符串表达式值为“真”的数据包才会被保留。这种字符串通常由一个或者多个原语所组成。每个原语又由一个标识符(名称或者数字)组成,后面跟着一个或者多个限定符。
伯克利包过滤中的限定符有下面3种。
•type:这种限定符表示指代的对象,例如IP地址、子网或者端口等。常见的有host(用来表示主机名和IP地址)、net(用来表示子网)、port(用来表示端口)。如果没有指定的话,就默认为host。
•dir:这种限定符表示数据包传输的方向,常见的有src(源地址)和dst(目的地址)。如果没有指定的话,默认为“src or dst”。例如“192.168.1.1”就表示无论源地址或者目的地址为192.168.1.1的都使得这个语句为真。
•proto:这种限定符表示与数据包匹配的协议类型,常见的就是ether、ip、tcp、arp这些协议。
伯克利包过滤中的标识符指的就是那些进行测试的实际内容,例如IP地址192.168.1.1,子网192.168.1.0/24,或者端口号8080都是常见的标识符。host 192.168.1.1和port 8080就是两个比较常见的原语,我们还可以用and、or和not把多于一个原语组成一个更复杂的过滤命令。例如host 192.168.1.1 and port 8080也是符合规则的过滤命令。
下面给出了一些常见的原语实例。
•host 192.168.1.1,当数据包的目标地址或者源地址为192.168.1.1时,过滤语句为真。
•dst host 192.168.1.1,当数据包的目标地址为192.168.1.1时,过滤语句为真。
•src host 192.168.1.1,当数据包的源地址为192.168.1.1时,过滤语句为真。
•ether host 11:22:33:44:55:66,当数据包的以太网源地址或者目的地址为11:22:33: 44:55:66时,过滤语句为真。
•ether dst 11:22:33:44:55:66,当数据包的以太网目的地址为11:22:33:44:55:66,过滤语句为真。
•ether src 11:22:33:44:55:66,当数据包的以太网源地址为11:22:33:44:55:66,过滤语句为真。
•dst net 192.168.1.0/24,当数据包的IPv4/v6的目的地址的网络号为192.168.1.0/24时,过滤语句为真。
•src net 192.168.1.0/24,当数据包的IPv4/v6的源地址的网络号为192.168.1.0/24时,过滤语句为真。
•net 192.168.1.0/24,当数据包的IPv4/v6的源地址或目的地址的网络号为192.168.1.0/24时,过滤语句为真。
•dst port 8080,当数据包是tcp或者udp数据包且目的端口号为8080时,过滤语句为真。
•src port 8080,当数据包是tcp或者udp数据包且源端口号为8080时,过滤语句为真。
•port 8080当数据包的源端口或者目的端口为8080时,过滤命令为真。所有的port前面都可以加上关键字tcp或者udp。
如果需要对数据包进行更细微的操作,伯克利包过滤也支持精确到位的操作。具体的语法为proto[expr:size],这里面的proto指代协议,expr表示相对给出协议层的字节偏移量,size表示要操作的字节数。其中size的值是可选的,可以是1、2、4中的一个,默认值为1。
例如,一个IP数据包头部的长度为20字节(图2-2中8位为1字节),其中的第12、13、14、15这4个字节表示的就是这个数据包的源地址。图2-2给出了一个IP数据包头的格式。
图2-2 IP数据包头的格式
现在我们使用这个格式来改写dst host 192.168.1.1,这里面要操作的dst host是源地址,它位于IP数据包头的第12,13,14,15位,expr的值为12,长度size的值为4,地址192.168.1.1转换为十六进制为“0xc0a80101”,最后就可以写成:
ip[12:4] =0xc0a80101
这种偏移量的写法在很多情形下是相当有用的,例如对各种类型icmp协议的过滤,对各种TCP协议标志位的过滤。