aboutsummaryrefslogtreecommitdiff
path: root/net/py-pypcap
diff options
context:
space:
mode:
authorWesley Shields <wxs@FreeBSD.org>2011-10-02 02:55:21 +0000
committerWesley Shields <wxs@FreeBSD.org>2011-10-02 02:55:21 +0000
commit372b4b4c172cde52487d91f3f73db5ce848090b3 (patch)
tree7af296fe398b10237df3b6f5a537ec9b047acf38 /net/py-pypcap
parent191e965b712f16c4dcfbc1bee8c1784ecedea1f0 (diff)
downloadports-372b4b4c172cde52487d91f3f73db5ce848090b3.tar.gz
ports-372b4b4c172cde52487d91f3f73db5ce848090b3.zip
Notes
Diffstat (limited to 'net/py-pypcap')
-rw-r--r--net/py-pypcap/Makefile4
-rw-r--r--net/py-pypcap/files/patch-pcap.pyx221
2 files changed, 223 insertions, 2 deletions
diff --git a/net/py-pypcap/Makefile b/net/py-pypcap/Makefile
index 79d4ec7d209c..6d22b637f5bc 100644
--- a/net/py-pypcap/Makefile
+++ b/net/py-pypcap/Makefile
@@ -7,7 +7,7 @@
PORTNAME= pypcap
PORTVERSION= 1.1
-PORTREVISION= 3
+PORTREVISION= 4
CATEGORIES= net python
MASTER_SITES= ${MASTER_SITE_GOOGLE_CODE}
PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX}
@@ -25,6 +25,6 @@ PYDISTUTILS_PKGNAME= pcap
PLIST_FILES= %%PYTHON_SITELIBDIR%%/pcap.so
post-patch:
- ${RM} ${WRKDIR}/${PORTNAME}-${PORTVERSION}/pcap.c
+ @${RM} ${WRKDIR}/${PORTNAME}-${PORTVERSION}/pcap.c
.include <bsd.port.mk>
diff --git a/net/py-pypcap/files/patch-pcap.pyx b/net/py-pypcap/files/patch-pcap.pyx
new file mode 100644
index 000000000000..763ad1d97b3b
--- /dev/null
+++ b/net/py-pypcap/files/patch-pcap.pyx
@@ -0,0 +1,221 @@
+--- ./pcap.pyx.orig 2011-10-01 22:35:33.141146678 -0400
++++ ./pcap.pyx 2011-10-01 22:35:39.416147272 -0400
+@@ -1,7 +1,7 @@
+ #
+ # pcap.pyx
+ #
+-# $Id: pcap.pyx,v 1.20 2005/10/16 23:00:11 dugsong Exp $
++# $Id: pcap.pyx 101 2010-07-16 08:20:16Z kosma@kosma.pl $
+
+ """packet capture library
+
+@@ -17,9 +17,11 @@
+ __version__ = '1.1'
+
+ import sys
++import struct
+
+ cdef extern from "Python.h":
+ object PyBuffer_FromMemory(char *s, int len)
++ int PyObject_AsCharBuffer(object obj, char **buffer, int *buffer_len)
+ int PyGILState_Ensure()
+ void PyGILState_Release(int gil)
+ void Py_BEGIN_ALLOW_THREADS()
+@@ -42,6 +44,10 @@
+ unsigned int caplen
+ ctypedef struct pcap_t:
+ int __xxx
++ ctypedef struct pcap_if_t # hack for win32
++ ctypedef struct pcap_if_t:
++ pcap_if_t *next
++ char *name
+
+ ctypedef void (*pcap_handler)(void *arg, pcap_pkthdr *hdr, char *pkt)
+
+@@ -62,6 +68,13 @@
+ char *pcap_geterr(pcap_t *p)
+ void pcap_close(pcap_t *p)
+ int bpf_filter(bpf_insn *insns, char *buf, int len, int caplen)
++ int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
++ void pcap_freealldevs(pcap_if_t *alldevs)
++ int pcap_lookupnet(char *device,
++ unsigned int *netp,
++ unsigned int *maskp,
++ char *errbuf)
++ int pcap_sendpacket(pcap_t *p, char *buf, int size)
+
+ cdef extern from "pcap_ex.h":
+ # XXX - hrr, sync with libdnet and libevent
+@@ -134,16 +147,18 @@
+ raise IOError, 'bad filter'
+ def filter(self, buf):
+ """Return boolean match for buf against our filter."""
++ cdef char *p
+ cdef int n
+- n = len(buf)
+- if bpf_filter(self.fcode.bf_insns, buf, n, n) == 0:
++ if PyObject_AsCharBuffer(buf, &p, &n) < 0:
++ raise TypeError
++ if bpf_filter(self.fcode.bf_insns, p, n, n) == 0:
+ return False
+ return True
+ def __dealloc__(self):
+ pcap_freecode(&self.fcode)
+
+ cdef class pcap:
+- """pcap(name=None, snaplen=65535, promisc=True, immediate=False) -> packet capture object
++ """pcap(name=None, snaplen=65535, promisc=True, timeout_ms=None, immediate=False) -> packet capture object
+
+ Open a handle to a packet capture descriptor.
+
+@@ -152,6 +167,9 @@
+ or None to open the first available up interface
+ snaplen -- maximum number of bytes to capture for each packet
+ promisc -- boolean to specify promiscuous mode sniffing
++ timeout_ms -- requests for the next packet will return None if the timeout
++ (in milliseconds) is reached and no packets were received
++ (Default: no timeout)
+ immediate -- disable buffering, if possible
+ """
+ cdef pcap_t *__pcap
+@@ -161,7 +179,7 @@
+ cdef int __dloff
+
+ def __init__(self, name=None, snaplen=65535, promisc=True,
+- timeout_ms=500, immediate=False):
++ timeout_ms=0, immediate=False):
+ global dltoff
+ cdef char *p
+
+@@ -171,7 +189,7 @@
+ raise OSError, self.__ebuf
+ else:
+ p = name
+-
++
+ self.__pcap = pcap_open_offline(p, self.__ebuf)
+ if not self.__pcap:
+ self.__pcap = pcap_open_live(pcap_ex_name(p), snaplen, promisc,
+@@ -184,7 +202,7 @@
+ try: self.__dloff = dltoff[pcap_datalink(self.__pcap)]
+ except KeyError: pass
+ if immediate and pcap_ex_immediate(self.__pcap) < 0:
+- raise OSError, "couldn't set BPF immediate mode"
++ raise OSError, "couldn't enable immediate mode"
+
+ property name:
+ """Network interface or dumpfile name."""
+@@ -243,16 +261,6 @@
+ """Return datalink type (DLT_* values)."""
+ return pcap_datalink(self.__pcap)
+
+- def next(self):
+- """Return the next (timestamp, packet) tuple, or None on error."""
+- cdef pcap_pkthdr hdr
+- cdef char *pkt
+- pkt = <char *>pcap_next(self.__pcap, &hdr)
+- if not pkt:
+- return None
+- return (hdr.ts.tv_sec + (hdr.ts.tv_usec / 1000000.0),
+- PyBuffer_FromMemory(pkt, hdr.caplen))
+-
+ def __add_pkts(self, ts, pkt, pkts):
+ pkts.append((ts, pkt))
+
+@@ -288,18 +296,24 @@
+ raise exc[0], exc[1], exc[2]
+ return n
+
+- def loop(self, callback, *args):
+- """Loop forever, processing packets with a user callback.
+- The loop can be exited with an exception, including KeyboardInterrupt.
++ def loop(self, cnt, callback, *args):
++ """Processing packets with a user callback during a loop.
++ The loop can be exited when cnt value is reached
++ or with an exception, including KeyboardInterrupt.
+
+ Arguments:
+
++ cnt -- number of packets to process;
++ 0 or -1 to process all packets until an error occurs,
++ EOF is reached;
+ callback -- function with (timestamp, pkt, *args) prototype
+ *args -- optional arguments passed to callback on execution
+ """
+ cdef pcap_pkthdr *hdr
+ cdef char *pkt
+ cdef int n
++ cdef int i
++ i = 1
+ pcap_ex_setup(self.__pcap)
+ while 1:
+ Py_BEGIN_ALLOW_THREADS
+@@ -308,10 +322,22 @@
+ if n == 1:
+ callback(hdr.ts.tv_sec + (hdr.ts.tv_usec / 1000000.0),
+ PyBuffer_FromMemory(pkt, hdr.caplen), *args)
++ elif n == 0:
++ break
+ elif n == -1:
+ raise KeyboardInterrupt
+ elif n == -2:
+ break
++ if i == cnt:
++ break
++ i = i + 1
++
++ def sendpacket(self, buf):
++ """Send a raw network packet on the interface."""
++ ret = pcap_sendpacket(self.__pcap, buf, len(buf))
++ if ret == -1:
++ raise OSError, pcap_geterr(self.__pcap)
++ return len(buf)
+
+ def geterr(self):
+ """Return the last error message associated with this handle."""
+@@ -340,6 +366,8 @@
+ if n == 1:
+ return (hdr.ts.tv_sec + (hdr.ts.tv_usec / 1000000.0),
+ PyBuffer_FromMemory(pkt, hdr.caplen))
++ elif n == 0:
++ return None
+ elif n == -1:
+ raise KeyboardInterrupt
+ elif n == -2:
+@@ -364,3 +392,36 @@
+ raise OSError, ebuf
+ return p
+
++def findalldevs():
++ """Return a list of capture devices."""
++ cdef pcap_if_t *devs, *curr
++ cdef char ebuf[256]
++
++ status = pcap_findalldevs(&devs, ebuf)
++ if status:
++ raise OSError(ebuf)
++ retval = []
++ if not devs:
++ return retval
++ curr = devs
++ while 1:
++ retval.append(curr.name)
++ if not curr.next:
++ break
++ curr = curr.next
++ pcap_freealldevs(devs)
++ return retval
++
++def lookupnet(char *dev):
++ """
++ Return the address and the netmask of a given device
++ as network-byteorder integers.
++ """
++ cdef unsigned int netp
++ cdef unsigned int maskp
++ cdef char ebuf[256]
++
++ status = pcap_lookupnet(dev, &netp, &maskp, ebuf)
++ if status:
++ raise OSError(ebuf)
++ return struct.pack('I', netp), struct.pack('I', maskp)