<div dir="ltr">Thanks for the suggestions Gisle and Guy!<br><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Apr 23, 2013 at 6:46 PM, Gisle Vanem <span dir="ltr"><<a href="mailto:gvanem@broadpark.no" target="_blank">gvanem@broadpark.no</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Unless as Guy hints, the layout of 'FILE' is different in your program and what it is in winpcap.lib. <br></blockquote><div><br><br></div><div>That's what I'm thinking now.<br><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
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:<br>
<br>
your_file = fopen ("bla-bla.pcpa", "rb");<br>
...<br>
setvbuf (your_file, NULL, _IONBF, 0); <br>
</blockquote><div><br><br></div><div>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.<br>
<br>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.<br>
<br></div><div>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.<br><br></div><div>Anyway, the output values depend on the pcap file used for testing. An example output on macosx:<br>
<br>File position after pcap_fopen_offline: 24<br>File position after pcap_next_ex: 1288<br>Expected file position: 1288 <br><br></div><div>While on Windows it prints:<br><br>File position after pcap_fopen_offline: 4096<br>
File position after pcap_next_ex: 4096<br>Expected file position: 1288<br><br></div><div>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.<br>
<br></div><div><br></div><div><br></div><div>// test.cpp<br></div><div><br>#include <pcap.h><br>#include <cstdio><br>#include <iostream><br><br>int main(int argc, char* argv[])<br>{<br><br> char errbuff[PCAP_ERRBUF_SIZE];<br>
<br> FILE* myFile = fopen(argv[1], "rb");<br><br> //setvbuf(this->MyFile, NULL, _IONBF, 0);<br><br> pcap_t *pcapFile = pcap_fopen_offline(myFile, errbuff);<br> if (!pcapFile)<br> {<br> std::cout << "pcap error: " << errbuff << std::endl;<br>
return 1;<br> }<br><br> std::cout << "File position after pcap_fopen_offline: " << ftell(myFile) << std::endl;<br><br> const unsigned char* data;<br> struct pcap_pkthdr *header;<br><br>
pcap_next_ex(pcapFile, &header, &data);<br><br> std::cout << "File position after pcap_next_ex: " << ftell(myFile) << std::endl;<br> std::cout << "Expected file position: " << 24 + 16 + header->len << std::endl;<br>
<br> pcap_close(pcapFile);<br> fclose(myFile);<br><br> return 0;<br>}<br></div><div><br><br><br></div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Apr 23, 2013 at 6:46 PM, Gisle Vanem <span dir="ltr"><<a href="mailto:gvanem@broadpark.no" target="_blank">gvanem@broadpark.no</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">"Pat Marion" <<a href="mailto:pat.marion@kitware.com" target="_blank">pat.marion@kitware.com</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I took a look at the implementation of pcap_hopen_offline(). I see that it<br>
takes the input FILE* and creates a new FILE* using a series of function<br>
calls:<br>
</blockquote>
<br></div>
Not excactly. It takes an OS low level handle and gives you a 'FILE*'<br>
suitable for the CRT you're using in your program. '_get_osfhandle()' is documented here:<br>
<a href="http://msdn.microsoft.com/en-us/library/ks2530z6(v=vs.71).aspx" target="_blank">http://msdn.microsoft.com/en-<u></u>us/library/ks2530z6(v=vs.71).<u></u>aspx</a><div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
_fileno()<br>
_get_osfhandle()<br>
_open_osfhandle()<br>
_fdopen()<br>
<br>
So, if I understand correctly, it is creating a new FILE* that is relative<br>
to its own CRT.<br>
</blockquote>
<br></div>
Yes.<div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I think that means I can no longer use any information I<br>
query about the original input FILE*, because winpcap has created its own<br>
FILE* stream to read from.<br>
</blockquote>
<br></div>
But check 'pcap_hopen_offline()' and see that it's calling '_fdopen()'.<br>
The ret-val of that is a 'FILE*' suitable for the CRT winpcap.lib was built<br>
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. <br><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
So that leads me to think that my plan to use ftell() to record file<br>
positions of packets, and fseek() to jump to the begining of packets, is<br>
not going to work on Windows. What do you think? <br>
</blockquote>
<br></div>
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:<br>
<br>
your_file = fopen ("bla-bla.pcpa", "rb");<br>
...<br>
setvbuf (your_file, NULL, _IONBF, 0); <br>
Ref.<br>
<a href="http://msdn.microsoft.com/en-us/library/86cebhfs(v=vs.71).aspx" target="_blank">http://msdn.microsoft.com/en-<u></u>us/library/86cebhfs(v=vs.71).<u></u>aspx</a><div class="HOEnZb"><div class="h5"><br>
<br>
--gv<br>
______________________________<u></u>_________________<br>
Winpcap-users mailing list<br>
<a href="mailto:Winpcap-users@winpcap.org" target="_blank">Winpcap-users@winpcap.org</a><br>
<a href="https://www.winpcap.org/mailman/listinfo/winpcap-users" target="_blank">https://www.winpcap.org/<u></u>mailman/listinfo/winpcap-users</a><br>
</div></div></blockquote></div><br></div>