我可以将内存中的数据提交到 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建议。
以 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建议。