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. iOS开发网络篇—网络编程基础

    iOS开发网络篇—网络编程基础 一.为什么要学习网络编程 1.简单说明 在移动互联网时代,移动应用的特征有: (1)几乎所有应用都需要用到网络,比如QQ.微博.网易新闻.优酷.百度地图 (2)只有通过 ...

  2. Redis应用场景(转)

    (来源:http://www.cnblogs.com/shanyou/archive/2012/09/04/2670972.html) Redis常用数据类型 Redis最为常用的数据类型主要有以下五 ...

  3. JavaScript Array对象 知识点总结

    1 isArray方法 该方法是Array对象的静态方法,用来判断一个值是否为数组,它可以弥补typeof运算符的不足. 用法是Array.isArray(array实例) 通用的判断对象数据类型的方 ...

  4. WeX5 快速开发平台 V3.6 正式版发布

    WeX5 V3.6 正式版核心特性:一.打包特性增强: 1- 提供多WebView选择,引入腾讯X5引擎,可自动适配移动设备环境进行切换,使通过X5打包生成的App具备更高的兼容性及更小的文件尺寸: ...

  5. [Python模式]策略模式

    策略模式 定义了算法族,分别封装起来,让它们之间可以互相替换.此模式让算法的变化独立于使用算法的客户. 作为动态语言,Python实现策略模式非常容易,只要所有算法提供相同的函数即可. import ...

  6. Umap2:开源USB host安全评估工具

    Umap2是一款由NCC Group和Cisco SAS小组开发的.基于python的USB host安全评估工具. 它拥有第一版所支持的所有功能: umap2emulate:USB设备枚举 umap ...

  7. (转)解决Android SDK Manager无法更新或下载太慢问题

    原帖地址:http://blog.csdn.net/exlsunshine/article/details/22208857 天朝的网络...哎~真是无语...还好最近装了谷歌的chrome浏览器+红 ...

  8. 极简版 react+webpack 脚手架

    目录结构 asset/ css/ img/ src/ entry.js ------------------------ 入口文件 .babelrc index.html package.json w ...

  9. /proc/uptime详解

    From:http://smilejay.com/2012/05/proc_uptime/ 在Linux中,我们常常会使用到uptime命令去看看系统的运行时间,它与一个文件有关,就是/proc/up ...

  10. 2015GitWebRTC编译实录16

    新问题,看应该是视频编解码那里出问题了.找找看.WebRtc VoiceEngine codecs:ISAC/16000/1 (103)ISAC/32000/1 (104)Unexpected cod ...