luffy1 / pypcap

Automatically exported from code.google.com/p/pypcap
Other
0 stars 0 forks source link

No timeout in pcap.next(), setnonblock() not working correctly #7

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
pcap.pcap.__init__() has an undocumented parameter "timeout_ms=500" which
is passed to WinPcap. WinPcap's pcap_next_ex() function returns after this
time (in milliseconds) if no packets were received. The return code is 0 in
this case. But in our pcap.__next__() method, we do not deal with this
return code but just continue listening. This leads to problems, for
example with non-blocking I/O.

Example:
I want to stop receiving packets when a given timeout (e.g. an inter-packet
interval) has been reached. Moreover the user should be able to interrupt
at any time with Ctrl-C.

-- test.py --
import pcap, time
pc = pcap.pcap()
interval = 2
while True:
    start = time.time()
    print "Waiting for next packet..."
    ts, pkt = pc.next()
    end = time.time()
    print "Packet received: %s (%s) %r " % (ts, end - start, pkt)
    if end - start > interval:
        print "Max inter-packet interval reached. Quitting."
        break
--------------

Run test.py on an empty LAN. The program prints "Waiting for next
packet..." and blocks in pc.next() until a packet is received (which can be
long after the supposed interval has elapsed). Ctrl-C has no effect either
before the next packet is received.

And inserting pc.setnonblock(True) in order to switch to non-blocking I/O
mode doesn't change anything.

My config:
pypcap 1.1 on Windows XP SP2, WinPcap 4.0.1 (packet.dll 4.0.0.901), Python 2.5 

Suggested patch: see attachment

The important part are the last two changes: If pcap_ex_next() hasn't
received any packets before the timeout (n==0) we just return None to the
caller (together with a timestamp). The rest is only for compatibility: If
a user explicitly specifies a timeout, he now must take into account that
.next() will return None if no packets were received. If he doesn't specify
a timeout, everything is like before and .next() will wait forever for new
packets. 

Regards,
Dirk

Original issue reported on code.google.com by Dirk.L...@gmail.com on 18 Sep 2007 at 5:17

Attachments:

GoogleCodeExporter commented 9 years ago
Any chance that this patch (or something similiar) will be applied?
Scapy's Windows port would tremendously benefit from that. 
We've been shipping our own patched pypcap version [1] for over a year now and 
it
works nicely on Windows XP, but there are problems with Vista and I'd rather 
point
our users to the official pypcap version.

Thanks again for developing this nice library. 

Regards
Dirk

[1] http://trac.secdev.org/scapy/wiki/PypcapScapyWin

Original comment by Dirk.L...@gmail.com on 19 Feb 2009 at 8:02

GoogleCodeExporter commented 9 years ago
Applied. I truly apologize for the delay. Jeez. Life.

Original comment by dugsong on 15 Dec 2009 at 3:12

GoogleCodeExporter commented 9 years ago
Thank you very much for the fix!

My patch had a little error: in the docstring for the pcap class (line 149) 
"immediate=False, timeout_ms=None" should be switched to truly correspond with
pcap.__init__(). Maybe you'll want to change that. 

Thanks again,
Dirk

Original comment by Dirk.L...@gmail.com on 16 Dec 2009 at 8:37

GoogleCodeExporter commented 9 years ago
I did the change in the docstrings (also in the first line of the docstrings).

however this patch was a bit broken, you can see a new one checked in as r94 if 
you are interested.

Original comment by getxs...@gmail.com on 13 Jul 2010 at 11:02

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Yes, but if you check well in the code the select try to read on the 
filedescriptor every 1 second. Why setting a timeout if it doesn't return 
anything below 1 second ?
And plus from my C knowledge i think the timeout should be set in the for loop 
and not outside.

I think this library need an heavy rewrite.

Original comment by aker...@gmail.com on 12 Jul 2013 at 1:41