【发布时间】:2011-11-01 13:46:03
【问题描述】:
我尝试使用 dpkt 和 pcap 通过 Python 捕获 HTTP 下载。代码看起来像
...
pc = pcap.pcap(iface)
for ts, pkt in pc:
handle_packet(pkt)
def handle_packet(pkt):
eth = dpkt.ethernet.Ethernet(pkt)
# Ignore non-IP and non-TCP packets
if eth.type != dpkt.ethernet.ETH_TYPE_IP:
return
ip = eth.data
if ip.p != dpkt.ip.IP_PROTO_TCP:
return
tcp = ip.data
data = tcp.data
# current connection
c = (ip.src, ip.dst, tcp.sport, tcp.dport)
# Handle only new HTTP-responses and TCP-packets
# of existing connections.
if c in conn:
handle_tcp_packet(c, tcp)
elif data[:4] == 'HTTP':
handle_http_response(c, tcp)
...
在handle_http_response() 和handle_tcp_packet() 中,我读取tcp 数据包(tcp.data)的数据并将它们写入文件。但是我注意到我经常收到具有相同 TCP 序列号 (tcp.seq) 的数据包(在同一个连接上),但它们似乎包含相同的数据。此外,似乎并非所有数据包都被捕获。例如,如果我总结数据包大小,则结果值低于 http-header (content-length) 中列出的值。但是在 Wireshark 中我可以看到所有的包。
有谁知道我为什么会得到这些重复的数据包以及如何捕获属于 http-response 的每个数据包?
编辑:
在这里你可以找到完整的代码:pastebin.com。
运行时它会在标准输出中打印类似的内容:
Waiting for HTTP-Audio-responses ...
...
New TCP-Packet, len=1440, tcp-payload=5107680, con-len=5197150 , dups=57 , dup-bytes=82080
New TCP-Packet, len=1440, tcp-payload=5109120, con-len=5197150 , dups=57 , dup-bytes=82080
New TCP-Packet, len=1440, tcp-payload=5110560, con-len=5197150 , dups=57 , dup-bytes=82080
----------> FIN <----------
New TCP-Packet, len=1937, tcp-payload=5112497, con-len=5197150 , dups=57 , dup-bytes=82080
New TCP-Packet, len=0, tcp-payload=5112497, con-len=5197150 , dups=57 , dup-bytes=82080
如您所见,TCP 有效负载加上重复的接收字节 (5112497+82080=5194577) 小于下载的文件大小 (5197150)。此外,您可以看到我收到了 57 个重复的包(相同的 SEQ 和相同的 TCP 数据),并且在带有 FIN 标志的数据包之后仍然收到了包。
那么有没有人知道如何捕获属于该连接的所有数据包? Wireshark 可以看到所有数据包,我认为它也使用了 libpcap。
我什至不知道是我做错了什么,还是 pcap 库做错了什么。
EDIT2:
好的,看来我的代码是正确的:在 Wireshark 中,我保存了捕获的数据包并在我的代码中使用了捕获文件(pcap.pcap('/home/path/filename') 而不是pcap.pcap('eth0'))。我的代码完美地读取了所有包(在多个测试中)!由于 Wireshark 也使用 libpcap (afaik),我认为问题在于 lib pypcap 并没有为我提供所有包。
关于如何测试的任何想法?
我已经自己编译了 pypcap(主干),但这并没有改变任何东西 -.-
EDIT3:
好的,我将代码更改为使用 pcapy 而不是 pypcap 并且遇到了同样的问题:
从以前捕获的文件(使用 Wireshark 创建)读取数据包时,一切都很好,但是当我直接从 eth0 捕获数据包时,我错过了一些数据包。
有趣:当同时运行两个程序(一个使用 pypcap 和一个使用 pcapy)时,它们会捕获不同的数据包。例如一个程序多接收一个数据包。
但我仍然不知道为什么-.-
我认为 Wireshark 使用相同的 base-lib (libpcap)。
请帮忙:)
【问题讨论】:
-
您是否丢失了整个数据包,或者将数据包缩短了? pcap 有(曾经有?)默认情况下有一个小缓冲区,所以你不会(不是吗?)总是获取每个数据包的所有数据。
-
这是一个有趣的问题 :) 在 Wireshark 中,每个 TCP 数据包都有 1440 字节的数据。来自 pcap 的数据包也有 1440 字节的数据。下载的
content-length是5197150。TCP-packet-length的总和是5152510(除了与之前的数据包具有相同的SEQ并且没有HTTP-header-information的重复数据包)。差异(5197150-5152510=44640)是(总是)1440的倍数。所以我想我错过了整个数据包,对吧?