This is a static archive of our old Q&A Site. Please post any new questions and answers at ask.wireshark.org.

random access read and dissection of packets from a pcap file

0

Hello all,

I'm trying to do random access read on a growing pcap file, (program keeps track of previous EOF and then try to restart reading from this mark on growing file), for this i'm using fseek and ftell functions. But problem i'm facing is that, when i go to read the file second time ,from previous EOF, pcap_open_offline shows error " bad dump file format"

how to resolve this problem? is anything wrong about my logic ?

FILE* fp=fopen(a.pcap,"r");

if(...)

fseek(fp,size,SEEK_SET);

pcap_fopen_offline(fp,errbuf);

if(..)

size=ftell(fp);

asked 10 Jun '13, 12:42

Sanny_D's gravatar image

Sanny_D
0182021
accept rate: 50%

edited 10 Jun '13, 12:43


One Answer:

2

is anything wrong about my logic ?

Yes. You're assuming that a pcap_fopen_offline() call will work regardless of whether the FILE * you hand to it is positioned at the beginning of the file or not; it won't, because the first thing it does is attempt to read the file header, and if it's not at the beginning of the file, it won't read the file header, it'll read whatever's at that position in the file, which might be part of the file header but not all of the file header, or might be packet data.

If you're just trying to do the moral equivalent of tail -f on the file - i.e., if you're reading up to an EOF, and then trying to read more packets as they're added to the file - you might just try sequentially reading; you don't need to do random access. HOWEVER, bear in mind that, unless the program writing to the file is being very careful to, when it writes out additional packets, write out all the packet data - for example, if it's using the standard I/O library routines to write the file (as libpcap does, and tcpdump writes its capture files out with libpcap), it must do an fflush() whenever it writes out a group of packets to the file. To do that with newer versions of tcpdump when run with the -w flag, pass it the -U option.

If you're really trying to do random I/O, i.e. going back and rereading packets, and also do a sequential read of the file, you should probably open the file twice, each time with pcap_open_offline(), and do sequential access on one pcap_t and random access on the other pcap_t.

answered 11 Jun '13, 00:10

Guy%20Harris's gravatar image

Guy Harris ♦♦
17.4k335196
accept rate: 19%

this is what i am trying to do, indeed i am opening the file everytym.

while(1) {

    FILE *pfile=NULL;
pfile=fopen(tmp[esc_cnt].c_str(),"r");

if((size!=0) || (size!=-1)){
        if( fseek(pfile,size,SEEK_SET)==0)
                printf("\n fseeksizefile:%ld\n",size);fflush(stdout);

}
pd1 = pcap_fopen_offline(pfile, errbuf);
printf("\nerrbuf:%s\n",errbuf);
if(!pd1) {fflush(stdout);printf("\nNo Traffic For Selected Identities: Capture File Size Zero"); fflush(stdout);
        sleep(1); esc_cnt-- ;continue;
}

if(pd1)
{
        ll_type = pcap_datalink(pd1); // ll_type gloabal var
        int retval=0;
        retval = pcap_loop(pd1,-1, process_packet, NULL);

        if (retval == -1)
        {
                pcap_perror(pd1, "wshark-test: ");
                pcap_close(pd1);
                exit(EXIT_FAILURE);

        }

        size=ftell(pfile);
        printf("\n sizefile:%ld\n",size);fflush(stdout);
}</code></pre><p>~ ~</p></div><div id="comment-21923-info" class="comment-info"><span class="comment-age">(11 Jun '13, 04:50)</span> <span class="comment-user userinfo">Sanny_D</span></div></div><span id="21932"></span><div id="comment-21932" class="comment"><div id="post-21932-score" class="comment-score"></div><div class="comment-text"><p>Your earlier comment said</p><blockquote><p>does that mean, after opening it by pcap_open_offline then i should call fseek i.e fseek((pcap_file(pcap_t))) ?</p></blockquote><p>The answer to that is essentially "yes". Do</p><pre><code>pfile=fopen(tmp[esc_cnt].c_str(),&quot;r&quot;);

pd1 = pcap_fopen_offline(pfile, errbuf); if((size!=0) || (size!=-1)){ if( fseek(pfile,size,SEEK_SET)==0) printf("\n fseeksizefile:%ld\n",size);fflush(stdout);

}

so that you do the seek AFTER libpcap opens the file, not BEFORE it opens the file.

(Also, make sure you don’t keep an unlimited number of file handles open; eventually you will hit the maximum number of open files per process (most if not all UN*Xes have one; I don’t know whether Windows does) and subsequent opens will fail.)

(11 Jun ‘13, 11:38) Guy Harris ♦♦