c - 如何设置libpcap过滤器获取arp包

标签 c libpcap arp sniffing

我有 filter="ip or vlan",我将它传递给 libpcap,如下所示,它在我的应用程序中运行了很长时间,没有任何问题。

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

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

"ip or vlan or arp or rarp"

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

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

最佳答案

我检查了 BPF instructionsWireShark弄清楚会发生什么。以下是各种过滤器的 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 或 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 或 B 应该与 B 或 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 和 ip,那么检查偏移量 16 处的字节是有意义的:现在我们想要找到包含 IP 数据包的 VLAN 标记帧In such frames, there are two EtherType fields : 第一个(在偏移量 12 处)包含 VLAN EtherType 值 (0x8100),第二个(在偏移量 16 处)包含 IP 协议(protocol)的 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 或 vlan 或 arp 或 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 或 rarp 或 ip 或 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

关于c - 如何设置libpcap过滤器获取arp包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20968983/

相关文章:

C OpenMP - 缩减可扩展性

c - 在 scanf 中使用整数变量作为索引

c - 如何在 Ubuntu 的 eclipse 中以 root 身份调试应用程序?

C# 原始套接字 ARP 回复

c - 为什么在 C 中展平多维数组是非法的?

c - 声明一个有很多指针的函数

c++ - pcap 函数出现未解析的外部符号 (LNK 2001) 错误

linux-kernel - iptables 和 libpcap

c - 从C中的IP获取MAC地址

Flutter 我在 firebase listing 时收到的错误