我正在编写的数据包捕获实用程序遇到一些问题。我目前正在使用 pcapy 打开实时字节流和 dpkt 来解码数据包。我还想将数据包写入 .pcap 文件,该文件与 dpkt.Writer 对象一起使用,但是记录在 pcap 文件中的时间戳来自写入器将数据包写入 pcap 文件时,而不是网络接口时或内核收到消息。
我从文档中了解到,在编写时您可以提供 ts 供作者使用,但是我不明白如何从收到的数据包的标头中提取它。从我可以找到的示例中,这些示例显示了如何通过读取文件来打印时间戳,似乎我可以简单地打印从字节流接收到的元组的第一个值,但是当我这样做时,会出现以下错误:
TypeError: int() 参数必须是字符串、类似字节的对象或数字,而不是“Pkthdr”
错误很清楚:毫无疑问,我必须在 Pkthdr 对象中找到时间戳属性,但我在 pcapy 项目或 dpkt 中找不到任何解释如何解析“标题”的文档/示例
我也尝试使用 pypcap 库进行实时捕获,但输出是相同的。我还在 python 2.7.5 上尝试了相同的代码,因为我读到 dpkt 可能还不完全支持 python3,但在任一版本上的结果相同
#!/usr/bin/env python3.6
import pcapy
import dpkt
cap = pcapy.open_live("eth0", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
(header,packet) = cap.next()
writer.writepkt(packet, header)
print('packet printed')
为了证明 pcap 中的时间戳是从写入时开始的,我在再次写入相同的数据包之前添加了睡眠期。您将看到两者在标头时间戳中显示了约 1 秒的差异:
#!/usr/bin/env python3.6
import pcapy
import dpkt
import time
cap = pcapy.open_live("em2", 65435, True, 100)
writer = dpkt.pcap.Writer(open("test.pcap", 'wb+'))
while True:
(header,packet) = cap.next()
writer.writepkt(packet, )
time.sleep(1)
writer.writepkt(packet, )
print('packet printed')
我不太依赖 pcapy 或 dpkt,所以如果有更好的方法,我愿意切换这些库中的任何一个,但是我觉得有更多经验的人可以告诉我如何深入研究Pkthdr 对象,将时间戳提取为 str,然后在写入 pcap 时将其作为“ts”参数插入:
ts = %unpack from header%
writer.writepkt(packet, ts)
编辑:所以我查看了 pcapy 模块中 pkthdr 对象的源代码,发现了一些有用的东西:似乎有一个名为“getts”的函数可以从对象中获取时间戳:
static PyMethodDef p_methods[] = {
{"getts", (PyCFunction) p_getts, METH_VARARGS, "get timestamp tuple
(seconds, microseconds) since the Epoch"},
{"getcaplen", (PyCFunction) p_getcaplen, METH_VARARGS, "returns the length
of portion present"},
{"getlen", (PyCFunction) p_getlen, METH_VARARGS, "returns the length of
the packet (off wire)"},
{NULL, NULL} /* sentinel */
};
在我的 python 代码中,我调用了这样的函数:
timestamp = header.getts()
它返回一个元组,其中包含标头的秒数和微秒数,例如 (1555710256, 942645)。下一步是将其连接成一个数字并将其输入到 dpkt writer ts 中。希望我很快就会发布一个工作示例