I am porting my sniffer from C to Python using libpcap via ctypes. Here is the python code:
import ctypes, sys
from ctypes.util import find_library
if sys.platform == "darwin":
_pcap = ctypes.cdll.LoadLibrary(find_library("libpcap"))
elif sys.platform == "linux2":
_pcap = ctypes.cdll.LoadLibrary("libpcap.so")
errbuf = ctypes.create_string_buffer(256)
pcap_lookupdev = _pcap.pcap_lookupdev
pcap_lookupdev.restype = ctypes.c_char_p
dev = pcap_lookupdev(errbuf)
print dev
# create handler
pcap_create = _pcap.pcap_create
handle = pcap_create(dev, errbuf)
print handle
if not handle:
print "failed creating handler:",errbuf
exit()
# monitor mode
pcap_can_set_rfmon = _pcap.pcap_can_set_rfmon
print "can rfmon:",pcap_can_set_rfmon(handle)
On Linux it works perfectly fine, but on Mac OS X it runs into a segmentation fault when I use handle. The value of handle even is sometimes negative, sometimes positive. I already tried to change the return type of pcap_create to unsigned int, but that didn’t help, but I think it returns a wrong type under OS X…
I did a printf("size of pcap_t: %zu\n", sizeof(pcap_t *)); on both systems in C to get the size of pcap_t handler type. On Linux it says 4 and on OS X 8. But I I don’t know how to go on from this point…
Or am I on the wrong path? Does anyone have an idea?
Data types matter.
You need to tell ctypes that the return value of
pcap_create()is a pointer, and you need to tell it that the argument topcap_can_set_rfmon()is a pointer.You do this by doing
The
and
lines are required here. This code will work with both 32-bit and 64-bit pointers, so you can use it on 32-bit and 64-bit Linux and on 32-bit and 64-bit OS X (and 32-bit and 64-bit Solaris and 32-bit and 64-bit FreeBSD and…, with whatever changes are needed to the code to load the library – on most Un*xes shared libraries have names ending with “.so”, so if you don’t want to use
find_libraryon other Un*xes, the Linux code may suffice).