pynetwork / pypcap

pypcap - python libpcap module, forked from code.google.com/p/pypcap
Other
299 stars 75 forks source link

tests fail with libpcap-1.10.3 #113

Open vcunat opened 1 year ago

vcunat commented 1 year ago

They were fine with libpcap-1.10.1

=========================== short test summary info ============================
FAILED tests/test.py::test_pcap_dispatch - assert 6 == 0
FAILED tests/test.py::test_pcap_dispatch_ns - assert 6 == 0
========================= 2 failed, 9 passed in 2.15s ==========================
vcunat commented 1 year ago

To be clear, this is with pypcap-1.3.0 although the tag is missing in this repo.

guyharris commented 1 year ago
FAILED tests/test.py::test_pcap_dispatch - assert 6 == 0

With the top of the trunk, test_pcap_dispatch() is

def test_pcap_dispatch():
    def __cnt_handler(ts, pkt, d):
        d.append((ts, len(pkt)))
    p = pcap.pcap(relative_file('test.pcap'))
    d = []
    n = p.dispatch(-1, __cnt_handler, d)
    assert n == 0
    assert d == __packet_info

To quote the pcap_dispatch() man page:

   pcap_dispatch() returns the number of packets processed on success; this
   can be 0 if no packets were read from a live capture ... or if no more packets
  are available in a ``savefile.''

So the equivalent C or C++ code that directly calls pcap_dispatch() would fail with that test if "test.pcap" contains one or more packets. That file contains 6 packets, so pcap_dispatch() would return 6, not 0.

dispatch is defined as

    def dispatch(self, cnt, callback, *args):
        """Collect and process packets with a user callback,
        return the number of packets processed, or 0 for a savefile.

...

        n = pcap_dispatch(self.__pcap, cnt, __pcap_handler, <u_char *><void*>ctx)
        if ctx.exc:
            raise ctx.exc[0], ctx.exc[1], ctx.exc[2]
        return n

So dispatch should return the value returned by pcap_dispatch().

The comment about returning "0 for a savefile" was added in 85c468f940ffe8120af3a46a6369b8eaa99de735:

commit 85c468f940ffe8120af3a46a6369b8eaa99de735
Author: dugsong <dugsong@0225ec8c-8f27-0410-80df-577ead3473a2>
Date:   Wed Jan 26 19:17:17 2005 +0000

    fix docstring for dispatch() on a savefile

    git-svn-id: http://pypcap.googlecode.com/svn/trunk@37 0225ec8c-8f27-0410-80df-577ead3473a2

diff --git a/pcap.pyx b/pcap.pyx
index f046ba1..9029929 100644
--- a/pcap.pyx
+++ b/pcap.pyx
@@ -221,7 +221,7 @@ cdef class pcap:

     def dispatch(self, callback, arg=None, cnt=-1):
         """Collect and process packets with a user callback,
-        return the number of packets processed.
+        return the number of packets processed, or 0 for a savefile.

         Arguments:

libpcap 0.9.1 appears to be the first release of 2005; it was released in July. libpcap 0.8.3 was the release before that; the pcap man page from that release says of pcap_dispatch():

       The number of packets read is returned.  0 is returned  if  no  packets
       were  read  from  a  live capture ... or if no more packets are available
       in a ‘‘savefile.’’

so the documented behavior of pcap_dispatch() dates back at least that far.

If I compare the 1.10.1 code with the 1.10.3 code, I don't see anything obvious that would change what happens if you pass -1 as the count, so I'm not sure why the behavior would differ between 1.10.1 and 1.10.3.

So:

  1. change 85c468f940ffe8120af3a46a6369b8eaa99de735 should be reverted;
  2. the two tests in question should be changed to check that n is 6, not 0 (test_nano.pcap also has 6 packets).