PCAP数据包过滤器设置 及 过滤表达式语法

libpcap详解 libpcap(packet capture library),即数据包捕获函数库,是Unix/Linux平台下的网络数据包捕获函数库。它是一个独立于系统的用户层的包捕获API接口,为底层网络监测提供了一个可移植的框架。 一、工作原理 libpcap主要由两部分组成:网络分接头(network tap)和数据过滤器(packet filter)。网络分接头从网络设备驱动程序中收集数据进行拷贝,过滤器决定是否接收该数据包。libpcap利用BSD packet filter(BPF)算法对网卡接收到的链路层数 阅读详情

通常我们只对特定网络通信感兴趣。比如我们只打算监听Telnet服务(port 23)以捕获用户名和口令信息。获知对FTP(port 21)或DNS(UDP port 53)数据流感兴趣。可以通过pcap_compile()和pcap_setfilter来设置数据流过滤规则(filter)

函数原型:

 int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

p:表示pcap会话句柄;

fp:存放编译以后的规则;

str:规则表达式格式的过滤规则(filter),同tcpdump中的filter;

optimize:制定优化选项:0 false, true;

netmask:监听接口的网络掩码;

返回值:-1表示操作失败,其他值表成功。

int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

 p:表示pcap的会话句柄;

 fp:表示经过编译后的过滤规则;

 返回值:-1表示操作失败,其他值表成功。

 

示例代码:

#include <pcap.h>
 ...
 pcap_t *handle; 
 char dev[] "rl0"; 
 char errbuf[PCAP_ERRBUF_SIZE]; 
 struct bpf_program filter; 
 char filter_app[] "port 23"; 
 bpf_u_int32 mask; 
 bpf_u_int32 net; 
 pcap_lookupnet(dev, &net, &mask, errbuf);
 handle pcap_open_live(dev, BUFSIZ, 1, 0, errbuf);
 pcap_compile(handle, &filter, filter_app, 0, net);
 pcap_setfilter(handle, &filter); 

上面的代码设备rl0上以混杂模式监听所有发往或源自端口23的数据包。Pcap_lookupnet()函数返回给定接口的IP地址和子网掩码。

 

【语法】

wpcap的过滤器是以已声明的谓词语法为基础的。过滤器是一个ASCII字符串,它包含了一个过滤表达式。pcap_compile()把这个表达式编译成内核级的包过滤器。
这个表达式会选择那些数据包将会被堆存。如果表达式没有给出,那么,网络上所有的包都会被内核过滤引擎所认可。不然,只有那些表达式为'true'的包才会被认可。

这个表达式包含了一个或多个原语。原语通常包含了id(名字或序列),这些id优先于限定词。以下是三种不同的限定词:

输入(type)
指明了哪些东西是id所代表的。可能的输入是host,net和port。比如:`host foo',`net 128.3',`port 20'。如果没有输入限定词,就假定是host
方向(dir)
由id指明了一个特定的传输方向。可能的方向是src,dst,src or dst。比如,'src foo','dst net 128.3',`src or dst port ftp-data'。如果没有指定,就假定是src or dst。如果没有链路层(比如,像slip这样的点对点协议),那么限定词可以使用inbound和outbound,来指明一个方向。
协议(proto)
限定词限制了所匹配的协议。可能的协议有:ether,fddi,tr,ip,ip6,arp,rarp,decnet,tcp和udp。比如:`ether src foo',`arp net 128.3',`tcp port 21'。如果没有指定协议限定词,那么就假定所有的协议都会被允许。例如:'src foo'等价于'(ip or arp or rarp)src foo'(当然,不能有不符合语法的字母出现),'net bar'等价于'(ip or arp or rarp) net bar','port53'等价于'(tcp or udp) port 53'。
[ 'fddi'通常是'ether'的别名;解析器会认为它们是在特定网络接口上的数据链路层。FDDI的首部包含了和以太网很相似的源地址和目的地址,并且通常也包含了和以太网很相似的数据包类型。所以,在FDDI网域上使用过滤器和在以太网上使用过滤器基本一致。FDDI的首部还包括了其他的数据,不过你不能在过滤器表达式内表示他们。

同样的,'tr'也是'ether'的一个别名,它是较早被应用于FDDI的首部,也应用在令牌环网络首部。]

除了以上内容,还有一些特殊的限定词和上面的形式不太一样,它们是:gateway,broadcast,less,greater和一些算术表达式。这些内容会在下面和大家介绍。

我们可以使用and,or和not将原语连接起来,来构造一个更复杂的过滤表达式。例如:`host foo and not port ftp and not port ftp-data'。如果要简化输入,我们可以把已列出的id限定词省略。比如:`tcp dst port ftp or ftp-data or domain' 和 `tcp dst port ftp or tcp dst port ftp-data or tcp dst port domain'是完全等价的。

可使用的原语有:

dst host host
当IPv4/v6数据包的目标域(destination field)为host时为true,host既可以是地址,也可以是名字。
src host host
当IPv4/v6数据包的源域(source field)为host时为true。
host host
当IPv4/v6数据包的源域(source field)或目标域(destination field)为host时为true。以上任何一个host表达式可以是ip,arp,rarp或ip6开头,如下所示:
ip host host等价于:
ether proto ip and host host如果host是一个多IP地址,那么每一个地址都会被匹配。
ether dst ehost
当以太网的目的地址为ehost时为true。ehost可以是一个来自/etc/ether的名字,也可以是一个数字代号(参见 ethers(3N)for numeric format)。
ether src ehost
当以太网的源地址为ehost时为true。
ether host ehost
当以太网的目的地址,或源地址为ehost时为true。
gateway host
当host为网关时为true。即,以太网源地址或目的地址是host,但源地址和目的地址不同时为host。host必须能被机器的主机-IP地址(host-name-to-IP-address)机制找到(如主机名文件,DNS,NIS等),也能被主机-以太网地址(host-name-to-Ethernet-address)机制找到(如/etc/ethers等)。例如:
ether host ehost and not host hosthost / ehost均可使用名字或数字。这个语法目前在IPv6下不能工作。
dst net net
当IPv4/v6数据包的目的地址的网络号包含了net时为true。net可以是一个来自/etc/networks的名字,也可以是一个网络号(更多内容请参见 networks(4))。
src net net
当IPv4/v6数据包的源地址的网络号包含了net时为true。
net net
当IPv4/v6数据包的目的地址,或源地址的网络号包含了net时为true
net net mask netmask
当IP地址是 net ,子网掩码匹配 netmask 时为true。可能需要 src 或 dst加以限制。注意,这个语法不能应用于IPv6。
net net/len
当IP地址是 net ,子网掩码连续1的个数为 len 时为true。可能需要 src 或 dst加以限制。
dst port port
当数据包是ip/tcp, ip/udp, ip6/tcp 或 ip6/udp,并且目的端口号是port时为true。port可以是数字,或是在/etc/services中被使用的名字。(参见 tcp(4P) and udp(4P))。如果使用名字,那么端口号和协议都将被检测。如果使用数字,或者一个不明确的名字,那么只有端口号会被检测。(比如:dst port 513将打印tcp/login数据流和udp/who数据流。port domain将打印tcp/domain的数据流和udp/domain的数据流)。
src port port
当源端口号是 port时为true。
port port
当源端口号或目的端口号为 port 时为true。以上任何一个port表达式可以以关键字tcp或udp开头,如下所示:
tcp src port port只匹配源端口是 port 的tcp数据包。
less length
当数据包的长度小于等于length时为true。即:
len <= length.greater length
当数据包的长度大于等于length时为true。即:
len >= length.ip proto protocol
当数据包是IP数据包,并且它的协议类型为protocol时为true。protocol可以是一个数字,也可以是icmp, icmp6,igmp,igrp,pim,ah,esp,vrrp,udp 或 tcp中的一个。注意,tcp,udp, icmp是关键字,所以,它们要使用反斜杠()来转义,就好比C-shell中的\。注意,这个原语不会去追踪协议首部链。
ip6 proto protocol
当数据包是IPv6数据包,并且它的协议类型为protocol时为true。注意,这个原语不会去追踪协议首部链。
ip6 protochain protocol
当数据包是IPv6数据包,并且,在它的协议首部链中,包含了protocol类型的协议首部时,为true。例如:
ip6 protochain 6能匹配所有的,拥有TCP协议首部的IPv6的数据包。在IPv6首部和TCP首部之间,可能包含认证首部,路由首部和跳数选项首部。由这个原语所生成的BPF(BSD Packet Filter,包过滤机制)码是复杂的,而且不能被BPF优化器优化,所以,在某些程度上,它的速度比较慢。
ip protochain protocol
功能和 ip6 protochain protocol相同,只是这个应用于 IPv4。
ether broadcast
当数据包是以太网广播数据包时为true。关键字ether是可选的。
ip broadcast
当数据包是IP广播数据包时为true。它会检查所有的广播,包括地址全是0的和地址全是1的,然后,检查子网掩码。
ether multicast
当数据包是以太网多播数据包时为true。关键字ether是可选的。 下面是一个常用短语`ether[0] & 1 != 0'
ip multicast
当数据包是IP多播数据包时为true。
ip6 multicast
当数据包是IPv6多播数据包时为true。
ether proto protocol
当数据包是以太类型的protocol时为true。protocol可以是一个数字,也可以是ip, ip6, arp, rarp, atalk, aarp,decnet, sca, lat, mopdl, moprc,iso, stp, ipx, netbeui中的一个。注意,这些符号也都是关键字,所以,他们都需要用反斜杠()转义。
[在使用FDDI(比如'fddi protocol arp')和令牌环(比如'tr protocol arp')和其他大多数这种协议时,协议根据802.2逻辑链路控制(LLC)来识别,这些信息通常在FDDI或令牌环首部的开始。
当需要识别大多数协议的标识,比如FDDI或令牌环时, Tcpdump只检查LLC报头的ID数据域,它们以SNAP格式存储,并且,组织单位识别码(Organizational Unit Identifier(OUI))为0x000000,以封装以太网。它不会检查这个包是不是SNAP格式的,并在0x000000单元有OUI。
然而,iso是个特例,它会检查LLC首部的目的服务存取点DSAP(Destination Service Access Point)和源服务存取点SSAP(Source Service Access Point),stp和netbeui会检查LLC首部的DSAP,atalk会检查数据包是不是SNAP格式的,并且OUI是不是0x080007。Appletalk 同样如此。
在以太网的例子中,tcpdump检查大部分协议的以太网类型字段,iso,sap 和 netbeui除外,因为它们会检查802.3帧,然后检查LLC首部,就像它对FDDI和令牌环那样。atalk,它检查以太网帧的Appletalk etype和SNAP格式的以太网帧,arrp,它在以太网帧中检查Appletalk ARP etype,或是在OUI为0x000000的802.2 SNAP帧中查找,还有ipx,他会在以太网帧中检查IPX etype,在LLC首部检查IPX DSAP,没有用802.3封装的LLC首部的IPX,和SNAP帧中的IPX etype。]
decnet src host
当DECNET的源地址为host时为true,它可能是一个格式为'10.123'的地址,也可能是一个DECNET主机名。[DECNET主机名称只有在配置成可运行DECNET的Ultrix系统中才得到支持。]
decnet dst host
当DECNET的目的地址为host时为true。
decnet host host
当DECNET的源地址或目的地址为host时为true。
ip, ip6, arp, rarp, atalk, aarp, decnet, iso, stp, ipx, netbeui
缩写是:
ether proto pp 是以上协议中的一个。
lat, moprc, mopdl
缩写是:
ether proto pp 是以上协议中的一个。注意: tcpdump 目前并不知道,如何解析出这些协议。
vlan [vlan_id]
当数据包是IEEE 802.1Q VLAN数据包时为true。若[vlan_id]被指定,则仅当数据包为指定的vlan_id,值才为true。注意,在假设数据包为VLAN数据包的前提下,表达式中的第一个关键字vlan会改变剩余表达式的解码偏移量。
tcp, udp, icmp
缩写是:
ip proto p or ip6 proto pp 是以上协议中的一个。
iso proto protocol
当数据包的协议类型为protocol的OSI数据包时值为true。Protocol可以是一个数字或以下名称中的一个:clnp,esis或isis。
clnp, esis, isis
缩写是:
iso proto pp 是以上协议中的一个。注意,tcpdump并不能完成这些协议的全部解析工作。
expr relop expr
若关系式如下:relop是 >, <, >=, <=, =, != 中的一个,并且expr是一个由正整常数(用标准C语言的语法表示),标准二进制运算符[ +, -, *, /, &, | ],运算符的长度,和指定数据包存取,则值为true。要存取数据包内的数据,可以使用以下的语法:
proto [ expr : size ]
Proto 是 ether, fddi, tr, ip, arp, rarp, tcp, udp, icmp or ip6中的一个,它为索引操作指明了协议层。注意,tcp,udp和其他较高层的协议类型只能应用于IPv4,而不能用于IPv6(这个问题可能在将来能得到解决)。被指定的协议层的字节偏移量由expr给出。Size是可选的,它指明了数据域中,我们所感兴趣的字节数。它可以是1,2,或4,默认为1。运算符的长度,由关键字len给出,指明了数据包的长度。
例如,`ether[0] & 1 != 0'会捕捉所有的多播数据流。表达式`ip[0] & 0xf != 5'能捕捉所有带可选域的IP数据包。表达式`ip[6:2] & 0x1fff = 0'仅捕捉未分段的数据报和段偏移量是0的数据报。这个检查隐含在tcp和udp的下标操作中。例如,tcp[0]通常指第一个字节的TCP首部,而不是指第一个字节的分段。

有些偏移量和域值可以以名字来表示,而不是数值。以下协议首部域的偏移量是正确的:icmptype (ICMP 类型域), icmpcode (ICMP 代码域), and tcpflags (TCP 标志域)。

ICMP 类型域有以下这些: icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect, icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob, icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq, icmp-maskreply.

TCP 标志域有以下这些: tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-push, tcp-ack, tcp-urg.

原语可以用以下内容组合:

用圆括号括起来的原语和操作符 (圆括号在Shell中是特殊符号,所以必须要转义)。
取反操作 (`!' 或 `not').
连接操作 (`&&' 或 `and').
选择操作 (`||' 或 `or').
取反操作的优先级最高。连接操作和选择操作有相同的优先级,并且它们的结合方向为从左向右。注意:做连接的时候是需要显示的 and 操作符的,而不是把要连接的东西写在一起。

如果给出一个标识符,却没有关键字,那么就会假定用最近使用的关键字。例如:

not host vs and ace等价于
not host vs and host ace不能和下面的混淆
not ( host vs or ace )表达式参数即可以作为单个参数,也可以作为多个参数传递给tcpdump,后者更加方便一些。一般的,如果表达式包含一个Shell的元字符,那么用一个参数传递比较容易,最好把它括起来,多个参数在传递前,用空格连接起来。

本篇文章来源于 中国协议分析网|www.cnpaf.net 原文链接:http://www.cnpaf.net/Class/winpcap/200810/23011.html

PACP学习笔记三:PCAP方法说明 描述 用于创建数据包捕获句柄()以查看网络上的数据包。 source 是一个字符串,指定要打开的网络设备;在具有 2.2 或更高版本内核的 Linux 系统上,可以使用“any”或 NULL 的源参数来捕获来自所有接口的数据包。 返回的句柄必须先用 激活,然后才能用它捕获数据包;捕获的选项,例如混杂模式,可以在激活之前在句柄上设置。 成功时返回 pcap_t *,失败时返回 NULL。如果返回 NULL,则 errbuf 会填充适当的错误消息。假设 errbuf 至少能够保存 PCAP_ERRBUF_S 阅读详情

相关推荐

Jnetpcap实现捕获过滤器和显示过滤器

目前在使用Jnetpcap开发一款实时流量监控系统,其中需要实现捕获过滤器和显示过滤器,记录一下,也很简单,更多是调用API。 一、捕获过滤器 主要是利用PcapBpfProgram这个类 使用方法: PcapBpfProgram filter = new PcapBpfProgram(); int res = pcap.compile(filter, expression...

放下矜持的博客 1578

epcap_compile:将 pcap-filter(7) 表达式编译为 BPF 程序

epcap_compile 是一个 Erlang 库,用于将 PCAP 过滤器编译为 BPF 程序(请参阅 pcap-filter(7))。 epcap_compile 使用 NIF 接口从 libpcap 包装 pcap_compile(3PCAP)。 警告 由于库直接将过滤字符串传递给 pcap_compile(3PCAP),因此 pcap_compile() 中的任何错误都可能导致 Erlang VM 崩溃。 不要使用来自不受信任来源的过滤器。 另请注意,非常大的过滤器可能会阻塞调度程序或导致堆栈溢出。 例如: epcap_compile:compile(string:copies("ip and ", 50000) ++ "ip"). 默认情况下不允许大于 8192 字节的过滤器。 请参阅 compile/2 的limit选项。 要求 libpcap 在 Ubuntu 上

使用wireshark分析tcpdump出来的pcap文件

个人认为tcpdump+wireshark是很精确的,之前在网上查阅移动端流量测试,大多讲tcpdump这部分很精细,但是没有讲到详细使用wireshark分析tcpdump到的.pcap文件,这里做一个详细的讲解,仅供大家参考。

zeze_Z的博客 2万+

winpCap中compile和nocap函数

int pcap_compile ( pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask ) 编译数据包过滤器,在可由内核级过滤引擎解释的程序中转换高级过滤表达式(请参阅过滤表达式语法)。 pcap_compile()用于将字符串str编译为过滤器程序。 program是指向bpf_program结构的指针,并由pcap_compile()填充。优化控制是否对结果代码执行优

西门吹雪 1416

WinPcap过滤表达式语法

WinPcap过滤表达式语法

Why So Serious? 2160

pcap_complie() 和 pcap_setfilter()

<br />Winpcap 提供(libpcap也提供)的一个强大特性是过滤引擎(filtering engine)。它提供了一个非常有效的接收网络流量的方法,并且它通常与Winpcap提供的抓包机制集成在一起。用于过滤数据包的函数是 pcap_complie()和pcap_setfilter()。<br /><br />       pcap_complie()使用一个包含高级布尔表达式的字符串并且产生一个能被过滤引擎集成到数据包驱动中的低级字节码。<br />       pcap_setf

4420

PCAP过滤器设置PCAP-FILTER )

NAME 名称 pcap-filter - packet filter syntax  pcap-filter - 包过滤语法 DESCRIPTION 描述 pcap_compile() is used to compile a string into a filter program. The resulting filter program can then be appl

edger2heaven的专栏 1万+

Rust pcap完全教程:从设备列表到BPF过滤器的完整实践

Rust pcap是一个强大的网络数据包捕获库,支持Linux、Windows和Mac系统。本教程将带你从基础的设备列表查询到高级的BPF过滤器配置,掌握使用Rust进行网络数据包捕获的核心技能。 ## 📋 快速入门:环境准备与安装 要开始使用Rust pcap库,首先需要在你的Rust项目中添加依赖。在`Cargo.toml`文件中加入以下内容: ```toml [dependencie

gitblog_00486的博客 660

PCAP过滤器

PCAP-FILTER NAME pcap-filter-packet filter syntax DESCRIPTION pcap_compile() 将字符串编译成过滤器程序。 合理的过滤器程序可以定义什么样的包可以给 pcap_loop(), pcap_dispatch(), pcap_next(), pcap_net_ex(). 过滤器表达式通常由一个 id(名字或者数字)...

deliaodun9945的博客 836

pcap过滤规则

wpcap过滤器是以已声明的谓词语法为基础的。过滤器是一个ASCII字符串,它包含了一个过滤表达式pcap_compile()把这个表达式编译成内核级的包过滤器。 这个表达式会选择那些数据包将会被堆存。如果表达式没有给出,那么,网络上所有的包都会被内核过滤引擎所认可。不然,只有那些表达式为'true'的包才会被认可。 这个表达式包含了一个或多个原语。原语通常包含了id(名字或序列),这些i

5422

Libpcap库编程指南--过滤数据包

WinPcap和Libpcap的最强大的特性之一,是拥有过滤数据包的引擎。 它提供了有效的方法去获取网络中的某些数据包,这也是WinPcap捕获机制中的一个组成部分。 用来过滤数据包的函数是 pcap_compile() 和 pcap_setfilter() 。 pcap_compile() 它将一个高层的布尔过滤表达式编译成一个能够被过滤引擎所解释的低层的字节码。有关布尔过滤表达式语法可以参见

脱离了低级趣味的流氓 6756

18.3 NPCAP自定义数据包过滤

NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库。它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用。与WinPcap一样,NPCAP库提供了一些API,使开发人员可以轻松地在其应用程序中捕获和处理网络数据包。NPCAP库可以通过WinPcap API进行编程,因此现有的WinPcap应用程序可以轻松地迁移到NPCAP库上。自定义数据包过滤其核心原理是使用`pcap_compile`函数,该函数用于编译一个过滤表达式并生成过滤程序。该函数可以把用户指

微软技术分享 1万+

pcap编程抓包

Programming with pcap 流程 决定要嗅探的接口 初始化pcap,告诉pcap需要嗅探的接口,创建会话 定义嗅探的一些规则 让pcap进入执行循环 关闭嗅探会话 设置接口 通过设置参数执行参数指定需要嗅探的接口 #include <stdio.h> #include <pcap.h> int main(int argc, char *argv[]) {...

qq_37411461的博客 1986

wireshark过滤器的使用

wireshark过滤器的使用

天赐好车的博客 413

过滤数据包

过滤数据包   WinPcap和Libpcap的最强大的特性之一,是拥有过滤数据包的引擎。 它提供了有效的方法去获取网络中的某些数据包,这也是WinPcap捕获机制中的一个组成部分。 用来过滤数据包的函数是 pcap_compile() 和 pcap_setfilter() 。 pcap_compile() 它将一个高层的布尔过滤表达式编译成一个能够被过滤

qinqijing198601的专栏 645

【libpcap】利用pcap实现抓包发包

#include <stdio.h> #include <string.h> #include <pcap.h> #define SNAP_LEN 65536 static char g_ftag[6] = {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}; /* struct pcap_pkthdr { struct ti...

m0_37754764的博客 2778
上一篇: 从微观看chrome :Singleton<T> 范型类
下一篇: 进程关系
Ericdm
博客等级 码龄14年 6粉丝 14原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值