Using this link as a guide, I’ve written a C program which writes a PCAP file to disk. The PCAP contains complete Ethernet/IP/TCP packets, with payload. And after my program is done, I can manually read the generated PCAP files in Wireshark, so I believe the code works great. Here’s the pseudocode:
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;
}
There is another program which does packet analysis and accepts PCAP files as input. (That program is nDPI, for anyone who is interested.) When I dig into the other program’s source code, I see that it uses pcap_loop()
to analyze the PCAP input. That makes sense. And when I manually submit my written-to-disk PCAP files to this program, the program analyzes them perfectly.
But writing my PCAPs to disk and then reading them from disk is too time-consuming. I’d love a solution that takes that u_char* pcapData
in memory and submits it directly to pcap_loop()
. In theory, this should work. I thought perhaps I could use a C tmpfile()
to do the trick.
But my attempt segfaulted, right on the call to pcap_loop()
. So I tried calling pcap_loop in my own code, just to see what happened. Here’s the modification:
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;
}
The above code segfaults right on the call to pcap_loop()
. The callback function is never reached. When I try to step into pcap_loop()
on my debugger (GDB), the code segfaults immediately. So all I really know is that pcap_loop()
is choking on the in-memory version of my PCAP file. I wish I knew why.
So… my approach is wrong. Has anyone ever dealt with an issue like this before? I can’t believe I’m the first. Thanks.
(FYI, I am coding on an Ubuntu platform, using GCC 7.4.0)
FULL DISCLOSURE :: I've also posted this issue here.
A pcap_t
is a descriptor for a supplier of packets.
Those packets can come from a file OR they can come from a capture device.
If the pcap_t
was opened with a call such as pcap_open_offline()
, which opens a pcap file, it refers to a file, but it is NOT a FILE *
. (And that's not what I intended to say with the post you say led you to that conclusion; please re-read it, more carefully. As a core libpcap developer, I know for certain what a pcap_t
is - and isn't.)
If you want to directly submit packets to nDPI, without writing out a file and having it read the file, if nDPI can read from a pipe, the best way to do this is by writing to a pipe, as the comments on another question you asked about this suggest.