Search code examples
cpcap

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


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.


Solution

  • 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.