如何设置libpcap过滤器以获取arp数据包

时间:2014-01-07 10:15:16

标签: c libpcap arp sniffing

我有filter =“ip或vlan”,我将它传递给libpcap,如下所示,它在我的应用程序中工作了很长时间没有任何问题。

pcap_set_filter(pdesc->pd, filter, 0, netp);

现在我被要求解析arp trafic。所以我设置了我的过滤器

  

“ip或vlan或arp或rarp”

。但是我的回调函数没有调用arp数据包,即使是ip数据包,我的函数仍被调用。

简而言之,我的问题是如何正确设置libpcap过滤器以从系统获取arp数据包?

1 个答案:

答案 0 :(得分:2)

我检查了BPF instructions中的WireShark来弄清楚会发生什么。以下是各种过滤器的BPF过滤程序:

1。简单案例:

过滤:vlan

if the frame is VLAN-tagged then 
  return true 
else 
  return false

过滤:ip

if the frame is not VLAN-tagged and the protocol is IP then 
  return true 
else 
  return false

过滤:arp

if the frame is not VLAN-tagged and the protocol is ARP then 
  return true 
else 
  return false

过滤:rarp

if the frame is not VLAN-tagged and the protocol is RARP then 
  return true 
else 
  return false

过滤:ip or arp or rarp

if the frame is not VLAN-tagged and the protocol is either IP, ARP or RARP then 
  return true 
else 
  return false

2。ipvlan结合使用可以发现搜索代码的顺序非常重要:

您的第一个过滤器是ip or vlan。它的伪代码如下:

if either the frame is not VLAN-tagged and the protocol is IP 
   or the frame is VLAN-tagged
then 
  return true 
else 
  return false

对于过滤器vlan or ip,我们希望看到:

if either the frame is VLAN-tagged
   or the frame is not VLAN-tagged and the protocol is IP
then
  return true
else
  return false  

这意味着相同,这是可以的,因为A or B应该与B or A相同,不应该。但是我们得到了这个:

(000) ldh      [12]
(001) jeq      #0x8100          jt 4    jf 2
(002) ldh      [16]
(003) jeq      #0x800           jt 4    jf 5
(004) ret      #65535
(005) ret      #0

这意味着类似下面的伪代码:

if either the frame is VLAN-tagged
   or the frame is not VLAN-tagged but it has an EtherType field shifted 4 bytes right, which says the protocol is IP
then
  return true
else
  return false  

这没有意义。线(002)是不必要的。说明应如下所示:

(000) ldh      [12]
(001) jeq      #0x8100          jt 3    jf 2
(002) jeq      #0x800           jt 3    jf 4
(003) ret      #65535
(004) ret      #0

也许我会因为这样说而被杀,但我认为这是libpcap中的错误。以上行(002) ldh [16]来自哪里?如果过滤器是vlan and ip,那么检查偏移量16处的字节是有意义的:现在我们想要找到包含IP数据包的 VLAN标记帧In such frames, there are two EtherType fields:第一个(偏移12)包含VLAN EtherType值(0x8100),第二个(偏移16)包含IP协议的EtherType(#0x800):

(000) ldh      [12]
(001) jeq      #0x8100          jt 2    jf 5
(002) ldh      [16]
(003) jeq      #0x800           jt 4    jf 5
(004) ret      #65535
(005) ret      #0

3. 为什么您的过滤器没有找到ARP和RARP数据包?

您的过滤器为ip or vlan or arp or rarp。这编译为:

(000) ldh      [12]
(001) jeq      #0x800           jt 6    jf 2
(002) jeq      #0x8100          jt 6    jf 3
(003) ldh      [16]
(004) jeq      #0x806           jt 6    jf 5
(005) jeq      #0x8035          jt 6    jf 7
(006) ret      #65535
(007) ret      #0

此代码有上述错误:libpcap尝试在偏移量16处找到ARP和RARP EtherType。

4. 解决问题的方法

您可以通过在过滤器的开头添加它们来避免错误arp or rarp or ip or vlan。这编译为:

(000) ldh      [12]
(001) jeq      #0x806           jt 5    jf 2
(002) jeq      #0x8035          jt 5    jf 3
(003) jeq      #0x800           jt 5    jf 4
(004) jeq      #0x8100          jt 5    jf 6
(005) ret      #65535
(006) ret      #0

这意味着:

if either the frame is not VLAN-tagged and the protocol is either IP, ARP or RARP,
   or the frame is VLAN-tagged
then 
  return true 
else 
  return false