Thanks for the suggestions Gisle and Guy!
On Tue, Apr 23, 2013 at 6:46 PM, Gisle Vanem <[email protected]> wrote: > Unless as Guy hints, the layout of 'FILE' is different in your program > and what it is in winpcap.lib. > That's what I'm thinking now. It could be that your Windows problem has something to do with I/O > buffering. I.e. '_ftell()' is lying (giving you a wrong file-position) > since your 'FILE*' is buffered. You could try to set the 'FILE* ' to > unbuffered with: > > your_file = fopen ("bla-bla.pcpa", "rb"); > ... > setvbuf (your_file, NULL, _IONBF, 0); > I gave this a shot, but it didn't have an effect. It does seem to be related to buffering though, because the file position reported by ftell is always greater than what I expect it to be, but never greater by more than 4096. I wrote a test program that demonstrates the problem. You can run the program by passing a pcap save filename as the only argument. It prints the file position after pcap_fopen_offline(), which is expected to be 24, and then it reads one packet with pcap_next_ex() and prints the file position again, which should be 24 + 16 + packet data length. 24 is the number of bytes in the pcap global header, 16 is the number of bytes in a packet header. Perhaps, as Guy suggests, I am making dangerous assumptions on the pcap file layout, and my general strategy of using file seeking is one that I will have to ultimately abandon. Anyway, the output values depend on the pcap file used for testing. An example output on macosx: File position after pcap_fopen_offline: 24 File position after pcap_next_ex: 1288 Expected file position: 1288 While on Windows it prints: File position after pcap_fopen_offline: 4096 File position after pcap_next_ex: 4096 Expected file position: 1288 My speculation is that file buffering is used by stdio, and ftell called within the winpcap dll would report the correct file read position, but ftell called by my program returns the location at the end of the read buffer. // test.cpp #include <pcap.h> #include <cstdio> #include <iostream> int main(int argc, char* argv[]) { char errbuff[PCAP_ERRBUF_SIZE]; FILE* myFile = fopen(argv[1], "rb"); //setvbuf(this->MyFile, NULL, _IONBF, 0); pcap_t *pcapFile = pcap_fopen_offline(myFile, errbuff); if (!pcapFile) { std::cout << "pcap error: " << errbuff << std::endl; return 1; } std::cout << "File position after pcap_fopen_offline: " << ftell(myFile) << std::endl; const unsigned char* data; struct pcap_pkthdr *header; pcap_next_ex(pcapFile, &header, &data); std::cout << "File position after pcap_next_ex: " << ftell(myFile) << std::endl; std::cout << "Expected file position: " << 24 + 16 + header->len << std::endl; pcap_close(pcapFile); fclose(myFile); return 0; } On Tue, Apr 23, 2013 at 6:46 PM, Gisle Vanem <[email protected]> wrote: > "Pat Marion" <[email protected]> wrote: > > I took a look at the implementation of pcap_hopen_offline(). I see that >> it >> takes the input FILE* and creates a new FILE* using a series of function >> calls: >> > > Not excactly. It takes an OS low level handle and gives you a 'FILE*' > suitable for the CRT you're using in your program. '_get_osfhandle()' is > documented here: > > http://msdn.microsoft.com/en-**us/library/ks2530z6(v=vs.71).**aspx<http://msdn.microsoft.com/en-us/library/ks2530z6(v=vs.71).aspx> > > > _fileno() >> _get_osfhandle() >> _open_osfhandle() >> _fdopen() >> >> So, if I understand correctly, it is creating a new FILE* that is relative >> to its own CRT. >> > > Yes. > > > I think that means I can no longer use any information I >> query about the original input FILE*, because winpcap has created its own >> FILE* stream to read from. >> > > But check 'pcap_hopen_offline()' and see that it's calling '_fdopen()'. > The ret-val of that is a 'FILE*' suitable for the CRT winpcap.lib was built > for. I fail to see why that shouldn't work. Unless as Guy hints, the > layout of 'FILE' is different in your program and what it is in > winpcap.lib. > >> So that leads me to think that my plan to use ftell() to record file >> positions of packets, and fseek() to jump to the begining of packets, is >> not going to work on Windows. What do you think? >> > > It could be that your Windows problem has something to do with I/O > buffering. I.e. '_ftell()' is lying (giving you a wrong file-position) > since your 'FILE*' is buffered. You could try to set the 'FILE* ' to > unbuffered with: > > your_file = fopen ("bla-bla.pcpa", "rb"); > ... > setvbuf (your_file, NULL, _IONBF, 0); > Ref. > > http://msdn.microsoft.com/en-**us/library/86cebhfs(v=vs.71).**aspx<http://msdn.microsoft.com/en-us/library/86cebhfs(v=vs.71).aspx> > > > --gv > ______________________________**_________________ > Winpcap-users mailing list > [email protected] > https://www.winpcap.org/**mailman/listinfo/winpcap-users<https://www.winpcap.org/mailman/listinfo/winpcap-users> >
_______________________________________________ Winpcap-users mailing list [email protected] https://www.winpcap.org/mailman/listinfo/winpcap-users
