如何使用 Scapy 过滤 IP 列表的数据包

How to filter packets for a list of IP using Scapy

我正在尝试过滤 Python 中特定网站的数据包(使用 Scapy)。我有网站可能的 IP(用于负载平衡)列表。我想过滤所有这些 IP 的数据包。我怎样才能做到这一点?

对于单个 IP,我使用以下代码:

bpf_filter = "ip and host " + addr
sniff(timeout=10, prn=pkt_callback, store=0)

由于您使用的是 cBPF(经典 BPF),过滤一组 IP 地址的唯一方法是将它们全部列出:

bpf_filter = "ip and ("
for addr in addresses[:-1]:
    bpf_filter = "%shost %s or " % (bpf_filter, addr)
bpf_filter = "%shost %s)" % (bpf_filter, addresses[-1])

其中,对于一组 IP 地址 [10.0.0.1, 10.0.0.2, 10.0.0.3],将 return:

ip and (host 10.0.0.1 or host 10.0.0.2 or host 10.0.0.3)

注意:您的设置中至少需要一个 IP 地址才能使上述工作正常进行。


为什么这是 cBPF 的限制?

你给 Scapy 的过滤器表达式然后被编译成 BPF bytecode。 BPF 字节码不允许向后跳转(因此循环)。此限制是确保过滤器在内核中执行时最终停止的简单方法。

如果允许向后跳转,您可以通过您的 IP 地址集编写一些更智能的查找。例如,您可以将它们存储在散列 table 中,并根据 O(1) 中的散列 table 检查数据包。 eBPF 实际上是可能的,据我所知,Scapy 还不支持它。