我可以将内存中的数据提交到 pcap_loop() 吗?

Can I Submit Data-In-Memory to pcap_loop()?

this link 为指导,我编写了一个 C 程序,将 PCAP 文件写入磁盘。 PCAP 包含完整的 Ethernet/IP/TCP 数据包,带有负载。在我的程序完成后,我可以在 Wireshark 中手动读取生成的 PCAP 文件,所以我相信代码运行良好。这是伪代码:

int main(int argc, char ** argv ){

    u_char* pcapData = generatePCAPData();     // malloc()’s and creates the PCAP
                                               // file as a chunk of memory

    int sizeOfPcapData = getPcapLen( pcapData );

    FILE *fd = fopen( "myPcapFile.pcacp", "w" );
    fwrite( pcapData, sizeOfPcapData, 1, fd );
    fclose( fd );

    free( pcapData );

    return 1;
}

还有另一个程序可以进行数据包分析并接受 PCAP 文件作为输入。 (该程序是 nDPI,对于任何感兴趣的人。)当我深入研究另一个程序的源代码时,我看到它使用 pcap_loop() 来分析 PCAP 输入。这就说得通了。当我手动将写入磁盘的 PCAP 文件提交给这个程序时,程序会完美地分析它们。

但是将我的 PCAP 写入磁盘然后从磁盘读取它们太耗时了。我想要一个将 u_char* pcapData 存储在内存中并将其直接提交给 pcap_loop() 的解决方案。从理论上讲,这应该有效。我想也许我可以使用 C tmpfile() 来解决这个问题。

但是我的尝试在调用 pcap_loop() 时出现了段错误。所以我尝试在我自己的代码中调用 pcap_loop,看看发生了什么。修改如下:

int main(int argc, char ** argv ){

    u_char* pcapData = generatePCAPData();         // as before

    int sizeOfPcapData = getPcapLen( pcapData );   // as before

    FILE* myTmpFile = tmpfile();
    if( myTmpFile == NULL )  return -1;

    fwrite( pcapData, sizeOfPcapData, 1, myTmpFile );

    if(pcap_loop( (pcap_t*)myTmpFile, 1, &myCallback, NULL) < 0){
        printf("ERROR!\n");
    }

    return 1;
}

上面的代码在调用 pcap_loop() 时出现段错误。永远不会到达回调函数。当我尝试在我的调试器 (GDB) 上进入 pcap_loop() 时,代码立即出现段错误。所以我真正知道的是 pcap_loop() 正在阻塞我的 PCAP 文件的内存版本。我希望我知道为什么。

所以……我的做法是错误的。以前有没有人处理过这样的问题?我不敢相信我是第一个。谢谢。

(仅供参考,我在 Ubuntu 平台上使用 GCC 7.4.0 进行编码)

完全披露 :: 我也发布了这个问题 here

对于关注此主题的任何人...解决方案是使用 库中的一个函数,pcap_fopen_offline()。这是我的解决方案:

#include <pcap.h>

int main(int argc, char ** argv ){

    u_char* pcapData = generatePCAPData();         // as before

    int sizeOfPcapData = getPcapLen( pcapData );   // as before

    FILE* myTmpFile = tmpfile();
    if( myTmpFile == NULL )  return -1;

    fwrite( pcapData, sizeOfPcapData, 1, myTmpFile );

    // ****************************************************
    pcap_t* myPcapFile = pcap_fopen_offline( myTmpFile, errBuff );
    // ****************************************************

    if(pcap_loop( myPcapFile, 1, &myCallback, NULL) < 0){
        printf("ERROR!\n");
    }

    return 1;
}

A pcap_t 是数据包供应商的描述符。

这些数据包可以来自文件或者它们可以来自捕获设备。

如果 pcap_t 是用 pcap_open_offline() 这样的调用打开的,它打开了一个 pcap 文件,它引用了一个文件,但是它是不是 FILE *。 (这不是我想说的 post 你说的导致你得出那个结论;请 re-read 它,更仔细。作为核心 libpcap 开发人员,我肯定知道什么是 pcap_t 是 - 而不是。)

如果你想直接向 nDPI 提交数据包,而不是写出文件并让它读取文件,如果 nDPI 可以从管道读取,最好的方法是写入管道,因为 the comments on another question you asked about this建议。