您可以在不将其全部加载到内存的情况下索引 PCAP 文件吗?

Can you index a PCAP file without loading it all into memory?

我必须看看相当大的 PCAP,大约 40GB。我现在正在做的是使用 PCAP++ 一次一个地解析 PCAP 并处理其中的数据。该数据被放入缓冲区以供查看。为了节省内存,我会在您继续通过 PCAP 时丢弃旧数据。这让我一次只能使用大约 150MB。但是,如果用户想返回并查看太早之前的数据,他们不能,因为它已被丢弃。

有什么方法可以查看 PCAP 文件并转到存储数据的数据包,如果用户想回头看,可以重新处理数据吗?似乎如果我想获得某些数据包,我将不得不重新加载文件并再次查看所有数据的每一部分,或者将 pcap 文件拆分成一大堆小块。

所以我想通了,简短的回答是否定的。 PCAP++ 不支持任何可以在 pcap 文件上建立索引或模拟索引的功能。我切换回 libpcap,(这也应该在 windows 中与 winpcap 一起工作,但我还没有测试过)以便使用不同的库来帮助整理需要完成的工作。要正确执行此操作,您需要使用指向 pcap 文件中的关键数据包(或所有数据包,取决于您想要什么)的文件指针。它是这样工作的:

#ifdef _MSC_VER
    pcap_t *pcap = pcap_open_offline((pcapPath.string()).c_str(), errbuf);
#else
    pcap_t *pcap = pcap_open_offline(pcapPath.c_str(), errbuf);
#endif

//-----------------------------
//... General Packet setup ...
//-----------------------------

vector<fpos_t*> pcapIndexer;
while(/*Get Next Packet*/){

    //Parse the packet and get required flag
    //to know if it is a critical packet

    if(/*Check some condition from the data*/){
        fpos_t* position;
#ifdef _MSC_VER
        pcap_fgetpos(pcap, position);
#else
        FILE* f = pcap_file(pcap);
        fgetpos(f, position);
#endif
        pcapIndexer.push_back(position);
    }
}
    

从上面的代码中,您将遍历每个数据包,并根据数据包中的数据,将该文件指针添加到文件指针向量中。然后一旦你需要加载一个数据包,你就创建一个新的 pcap_t 指针并使用它:

#ifdef _MSC_VER
    pcap_fsetpos(pcap, pcapIndexer[x]);
#else
    FILE* f = pcap_file(pcap);
    fsetpos(f, pcapIndexer[x]);
#endif

然后您可以从该点开始正常阅读。请注意,您必须 运行 遍历整个 pcap 文件才能填充此文件指针向量,但是如果您使用多线程,则可以使用早期数据包中的一些数据,而其余数据pcap 文件正在被读取并添加到向量中。这允许您加载 select 数量的数据,然后能够来回跳转以从 pcap 文件的其他位置获取数据。我希望这对遇到这种情况的其他人有所帮助。