我有一堆用lzma压缩的巨大pcap文件(> 10GB)。我需要在我的机器上解析它们,我没有足够的空间来首先解压缩它们。有很多lib可以从文件中传输lzma。问题出在libpcap方面,我已多次阅读它的API,并且无法找到解析缓冲区的任何方法。我在libs'中看到了什么。源代码是第一个reads the magic byte和file header fread
:
amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
...
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1, sizeof(hdr) - sizeof(hdr.magic), fp);
然后pcap_next_packet
也使用fread
to read next packet from file。因此看起来很难将缓冲区从lzma流传递给它。另一方面,这些函数是stored in pcap_t structure as pointers。所以我可以为它实现自己的程序,但是,这样我将不得不从libpcap复制很多代码。有没有人知道如何在不侵入libpcap的情况下做到这一点?
我是否遗漏了libpcap API中的内容?
更新:在@Martin和其他人的帮助下,我设法让它发挥作用。我将发布实现,因此寻找方法的人可以使用它。
if (check_file_exists("/path/to/file.pcap.xz")) {
return;
}
// first open a pipe
FILE *pipe = popen("xz -d -c /path/to/file.pcap.xz", "r");
if (!pipe) {
// handle error somehow
return;
}
char errbuff[256];
// note pcap_fopen_offline function that takes FILE* instead of name
pcap_t *pcap = pcap_fopen_offline(pipe, errbuff);
struct pcap_pkthdr *header;
uint8_t *data;
while (pcap_next_ex(pcap, &header, &data)) {
// handle packets
}
答案 0 :(得分:1)
特别是对于大型pcap文件,最好不要先将整个内容读入内存。要正确处理缓冲区管理,您需要了解pcap格式以获得正确的长度等。
您可以使用popen进行流式处理,例如:
char* cmd = asprintf("/usr/bin/xz -d -c %s", filename);
FILE* fp = popen(cmd , "r");
free(cmd);
然后从fp读取就好像它是未压缩的一样。你也可以创建一个包装函数,用于打开返回一个FILE *,它可以解决是否通过扩展来管理各种解压缩程序,或者只是做一个简单的fopen。
一般情况下,我发现常规管道比命名管道更可取,因为它可以节省(a)选择一个唯一的名称,以及(b)在所有错误情况下清理它们
或者只是手工解析pcap,格式相当简单,IIRC只是一个头结构,然后每个数据包一个。