如何使用Python按特定协议过滤pcap文件?

12 投票
8 回答
55051 浏览
提问于 2025-04-15 19:10

我有一些pcap文件,我想按协议进行过滤,也就是说,如果我想过滤HTTP协议,那么除了HTTP数据包之外的所有内容都会留在pcap文件里。

有一个叫做openDPI的工具,它非常适合我的需求,但它没有适用于Python语言的封装。

有没有人知道有什么Python模块可以满足我的需求?

谢谢

编辑 1:

HTTP过滤只是一个例子,我还有很多其他协议想要过滤。

编辑 2:

我试过Scapy,但我不知道怎么正确过滤。这个过滤器只接受伯克利数据包过滤器表达式,也就是说,我不能应用msn、HTTP或其他上层的特定过滤器。有人能帮我吗?

8 个回答

6

sniff支持离线选项,你可以把pcap文件作为输入。这样,你就可以在pcap文件上使用sniff命令的过滤功能。

>>> packets = sniff(offline='mypackets.pcap')
>>>
>>> packets
<Sniffed: TCP:17 UDP:0 ICMP:0 Other:0>

希望这对你有帮助!

14

我知道这个问题已经很老了,但我刚好看到,想分享一下我的答案。这是我这些年来遇到过的几个问题之一,我发现自己总是回到dpkt这个库。这个库最初是由非常厉害的dugsong开发的,主要用于创建和解析数据包。我感觉它的pcap解析功能是后来加上的,但结果证明这个功能非常有用,因为解析pcap文件、IP、TCP和TCP头部都很简单。真正耗时间的是解析那些更高级的协议!(在找到dpkt之前,我自己写过一个Python的pcap解析库)

关于如何使用pcap解析功能的文档有点薄弱。这里有一个我自己文件中的例子:

import socket
import dpkt
import sys
pcapReader = dpkt.pcap.Reader(file(sys.argv[1], "rb"))
for ts, data in pcapReader:
    ether = dpkt.ethernet.Ethernet(data)
    if ether.type != dpkt.ethernet.ETH_TYPE_IP: raise
    ip = ether.data
    src = socket.inet_ntoa(ip.src)
    dst = socket.inet_ntoa(ip.dst)
    print "%s -> %s" % (src, dst)

希望这能帮助下一个看到这个帖子的人!

20

这里有个用Scapy的简单例子,因为我刚写了一个:

pkts = rdpcap('packets.pcap')
ports = [80, 25]
filtered = (pkt for pkt in pkts if
    TCP in pkt and
    (pkt[TCP].sport in ports or pkt[TCP].dport in ports))
wrpcap('filtered.pcap', filtered)

这个代码会过滤掉那些既不是HTTP也不是SMTP的网络数据包。如果你想要所有的数据包,除了HTTP和SMTP,那么第三行应该改成:

filtered = (pkt for pkt in pkts if
    not (TCP in pkt and
    (pkt[TCP].sport in ports or pkt[TCP].dport in ports)))
wrpcap('filtered.pcap', filtered)

撰写回答