libpcap支持一种功能非常强大的过滤语言——“伯克利包过滤”语法。使用BPF过滤规则,你可以确定该获取和检查哪些流量,忽略哪些流量。BPF让你能够通过比较第2、3、4层协议中各个数据字段值的方法对流量进行过滤。BPF中内置了一些“基元”来指代一些常用的协议字段。可以用“host”、"prot"之类的基元写出非常简洁的BPF过滤规则,也可以检测位于指定偏移量上的字段(甚至可以是一个位)的值。BPF过滤器也可以由详尽的条件链和嵌套的逻辑“与”、“或”操作组成。

BPF基元

现在,构造一个BPF过滤器的最简单的办法就是使用BPF“基元”来指定协议、协议元素或者其他抓包规则。基元通常是由一个id(名称或序号)再加上一个或多个限定符组成的。

  • type限定符:规定了id名或id序号指的是哪种类型的数据,可能的type有host、net、prot和protrange
  • dir限定符:规定了流量是从id流进还是流出的(或两种兼有)。可能的dir有src、dst、ser or dst、src and dst、addr1、addr2、addr3和addr4
  • Proto限定符:规定了所匹配的协议。可能的proto有:ether、fddi、tr、wlan、ip、ip6、arp、rarp、decnet、tcp和udp

最常用的BPF基元要数“host id”,它是用来过滤与某台主机相关的流量的,其中id一栏中应该填上一个地址或主机名。输入“tcp and host 10.10.10.10”这样的过滤规则,将值获取流入/流出得做10.10.10.10的TCP流量,其他的所有帧都会被过滤掉。

举例说明:假设我们现在希望仅仅获取IP地址为192.168.0.1的计算机与除IP地址10.1.1.1之外的其他所有计算机在138、139和445端口上发送的所有通信,下面这个BPF过滤规则就能完成上述任务:

'host 192.168.0.1 and not host 10.1.1.1 and (port 138 or port 139 or port 445)'

常用的BPF基元有

• host id , dst host id , src host id
• net id , dst net id , src net id
• ether host id , ether dst host id , ether src host id
• port id , dst port id , src port id
• gateway id , ip proto id , ether proto id
• tcp, udp, icmp, arp
• vlan id

根据字节的值过滤数据包

BPF语言也可以用来检查帧内任意一个单字节字段(或多字节字段)的值是不是规定值。下面是一些例子:

ip[8]<64

这个过滤规则规定要抓取的是:所有自ip头偏移8个字节的那个单字节字段的值小于64的IP包。被检查的这个字段表示的是“包的存活时间”或称“TTL”。大多数Windows系统中TTL的默认值是128,所以这个过滤规则将丢弃局域网中所有来自Windows系统的流量,只获取所有来自Linux系统的流量(因为在LInux系统中TTL的默认起始值是64)

ip[9]!=1

这一过滤规则规定要抓取的是所有IP头部偏移9个字节的那个单字节字段的值不等于“1”的帧。因为IP头部偏移9个字节的这个字段表示的是嵌入协议,如果等于“1”则表示“ICMP”协议,所以这个过滤规则将抓取除ICMP包之外的所有流量。这一表达式也等价于基元“not icmp”。

icmp[0] = 3 and icmp[1] = 0

这个语句规定要抓取的是:所有ICMP头部偏移0个字节的那个单字节字段等于3,且偏移1个字段的单字节字段等于0的ICMP数据包。换而言之,这一过滤规则将只抓取ICMPtype为3,code为0的“网络不可达”消息。

tcp[0:2] = 31337

这个语句检查了一个多字节字段,它检查的是:TCP头部偏移0个字节起的一个多字节字段(2个字节),该字段表示的是TCP源端口。所以这个表达式就等价于BPF基元“src prot 31337”

ip[12:4] = 0xC0A80101

我们看到的这是一个4字节的比较,它检查的是IP头部偏移12个字节起的4个字节里存放的数据——源IP地址。注意这个表达式里使用了十六进制表示法。转换成十进制数字,它就是192.168.1.1(0xC0=192,0xA8=168,0x01=1)。所以这一过滤规则将捕获所有源IP地址为192.168.1.1的流量。

根据位(bit)的值过滤数据包

BPF语言还提供了一种方法让我们能检查更小的字段或精度更高的偏移量。具体做法是:我们先引用相关的字节,或多个字节,然后再用“位掩码”逐位地把我们需要检查的位分离出来。

假设要过滤所有IP头部中可选字段被启用的包(就是IP头的长度大于20个字节的包)。IP头部的低半个字节表示的是IP头的长度,以“word”(字)为单位(一个word等于4个字节)。我们只需要找出这半个字节的值大于5(5word*4个字节/word=20个字节)的包就等于找出所有IP头部大于20个字节的包了。具体做法是用位掩码“00001111”(或者0x0F)创建一个BPF过滤规则,通过逻辑“与”运算提取目标值。

ip[0] & 0x0F > 0x05

与之类似,如果我们要找出所有“不分片”标志位(位于IP头部偏移6个字节位置上的一位二进制位)被置1的IP包,我们亦可用二进制位掩码“01000000”(0x40)来表示我们只关心IP头部偏移6个字节位置上那个第二最高位的bit值是是不是1。

在构造位掩码是,如果对应的那一位是我们需要检查的,那就用1表示,否则就用0表示。

ip[6] & 0x40 != 0

伯克利包过滤(Berkeley Packet Filter,BPF)语言的更多相关文章

  1. Berkeley Packet Filter (BPF) BCC

    http://www.brendangregg.com/ebpf.html https://qmonnet.github.io/whirl-offload/2016/09/01/dive-into-b ...

  2. wireshark捕获表达式之Berkeley Packet Filter (BPF) syntax

    就网络抓包来说,绝大部分的情况下,我们都是对特定的ip/端口/协议进行捕获和分析,否则就会有大量的垃圾报文,使得分析和性能低下.大部分的抓包工具都采用BPF语法,具体可参考 http://biot.c ...

  3. ASPF(Application Specific Packet Filter)

    ASPF ASPF(Application Specific Packet Filter)是针对应用层的包过滤,其原理是检测通过设备的报文的应用层协议信息,记录临时协商的数据连接,使得某些在安全策略中 ...

  4. 伯克利SocketAPI(一) socket的C语言接口/最简单的服务器和对应的客户端C语言实现

    1. 头文件 2. API函数 3. 最简单的服务器和对应的客户端C语言实现 3.1 server #include <sys/types.h> #include <sys/sock ...

  5. BPF漫谈

    源起 最近看到国内两篇文章[1][2]先后翻译了就职于Netflix的性能分析大牛Brendan Gregg于2017年7月31日写的<Golang bcc/BPF Function Traci ...

  6. BPF for storage:一种受外核启发的反式

    BPF for storage:一种受外核启发的反式 译自:BPF for storage: an exokernel-inspired approach BPF主要用于报文处理,通过绕过网络栈提高报 ...

  7. PYTHON黑帽编程 4.1 SNIFFER(嗅探器)之数据捕获(下)

    上一节(<4.1 SNIFFER(嗅探器)之数据捕获(上)>)中, 我们讲解了通过Raw Socket的方式来编写Sniffer的基本方法. 本节我们继续来编写Sniffer,只不过使用现 ...

  8. 全面介绍eBPF-概念

    全面介绍eBPF-概念 前面介绍了BCC可观测性和BCC网络,但对底层使用的eBPF的介绍相对较少,且官方欠缺对网络方面的介绍.下面对eBPF进行全面介绍. 目录 全面介绍eBPF-概念 BPF概述 ...

  9. 在Wireshrak中使用过滤器——捕获过滤器

    过滤器可以让你找出你所希望进行分析的数据包.简单来说,一个过滤器就是定义了一定条件,用来包含或者排除数据包的表达式.如果你不希望看到一些数据包,你可以写一恶搞过滤器来屏蔽它们.如果你希望只看到某些数据 ...

随机推荐

  1. [HB2014 Week5] Allot 人员分配

    这两天决心专门搞好网络流了 - - 题解在什么瞎胡搞跟我说要连n+2和n+1容量为无穷的边…我看了下std才做的… 坑死人的地方就是,需要求多次网络流,每次别忘了把流给清空了…这次是用链表所以专门写了 ...

  2. [TD Cup 2014] TDL的YC牌 & TDL的幼儿园

    TDL的YC牌 传说中的置换群?反正不懂.我的思路竟然是对的,可是为何只有20分? (1)尼玛每行数据输出后回车不打! (2)写gcd函数脑残把a mod b写成a-b,大大减慢速度… (3)看标程才 ...

  3. [CQOI 2014] 数三角形 & 机械排序臂

    数三角形 bzoj 3505 要知道一个公式就是(a,b)和(x,y)两点所成线段上面的整点数是gcd(a-x,b-y)-1,通过枚举原点到map上任意一点所能成的三角形,再平移,得到要去掉的三点共线 ...

  4. MATLAB 物体识别算法说明:vision.ForegroundDetector, vision.BlobAnalysis

    在官方示例中,Motion-Based Multiple Object Tracking和Using Kalman Filter for Object Tracking都使用了下面两个算法进行物体的识 ...

  5. jetty和tomcat启动项目

    首先jetty和tomcat区别,不全面说,只说我理解的.jetty架构比tomcat更为简单.jetty是基于Handler来实现的,易于拓展,因此更适合于同时处理且长时间保持连接:tomcat的架 ...

  6. IEEE参考文献格式

    IEEE参考文献格式 由于国外期刊参考文献与国内参考文献的格式有很大区别,其中最常用的参考文献为会议论文.书籍.期刊文献,所以特别在此记录说明,方便以后使用. 会议论文(Published Confe ...

  7. Debian 8(jessie)下设置系统启动直接进入命令行,无GUI

    修改grub项 sudo vi /etc/default/grub 修改其中三项 ... GRUB_CMDLINE_LINUX_DEFAULT="quiet" GRUB_CMDLI ...

  8. 团队开发——冲刺1.d

    冲刺阶段一(第四天) 1.昨天做了什么? 完成部分界面设置,补充三层难度界面.游戏结束界面. 2.今天准备做什么? 优化界面细节.查看C#资料,再解决自己电脑的问题. 3.遇到什么困难? 已经固定好的 ...

  9. (spring-第19回【AOP基础篇】)基于AspectJ和Schema的AOP

    基于AspectJ就是基于@AspectJ注解,基于Schema就是全部依靠配置文件.那么首先要了解Java注解. Java注解初探 在JDK5.0中,我们可以自定义标签,并通过Java语言的反射机制 ...

  10. 球形环境映射之angular方式的两种形式

    图形学中,某些物体带有反射属性,会反射周围的环境.一种做法是沿着反射方向发一条光线,与场景求交,获取到交点的颜色值,作为反射的颜色.显然这种方法比较低效,更高效的方法是将被渲染物体所处的环境保存到一张 ...