I’m attempting to map libpcap using ctypes to python3.2 and I’m having a problem using callbacks with pcap_loop… here is the code ..
class c_int_hack:
def from_param(self, *args):
return ctypes.c_void_p
#void got_packet(u_char *args, const struct pcap_pkthdr *header,
# const u_char *packet)
CALLBACK=ctypes.CFUNCTYPE(ctypes.c_void_p,c_int_hack,ctypes.pointer(pkthdr),ctypes.POINTER(ctypes.c_ubyte))
#int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
def process(user,pkthdr,packet):
print("In callback:")
print("pkthdr[0:7]:",pkthdr.contents.len)
print("packet6:%2x",packet[6])
print("packet7:%2x",packet[7])
print("packet8:%2x",packet[8])
print("packet9:%2x",packet[9])
print("packet10:%2x",packet[10])
print("packet11:%2x",packet[11])
got_packet=CALLBACK(process)
if(pcap_loop(handle,ctypes.c_int(10), got_packet,"what") == -1):
err = pcap_geterr(handle)
print("pcap_loop error: {0}".format(err))
it seems to have a problem with the 2nd parameter which is the “c_int_hack”
Got Required netmask
Pcap open live worked!
Filter Compiled!
Filter installed!
Traceback (most recent call last):
File "./libpcap.py", line 72, in <module>
CALLBACK=ctypes.CFUNCTYPE(ctypes.c_void_p,c_int_hack,ctypes.pointer(pkthdr),ctypes.POINTER(ctypes.c_ubyte))
File "/usr/lib/python3.2/ctypes/__init__.py", line 99, in CFUNCTYPE
return _c_functype_cache[(restype, argtypes, flags)]
TypeError: unhashable type
THis is my first time doing work with ctypes so I’m rather confused at this point.
…… EDIT……….
So the prototype is trying to accept a pointer to a list of arguments. so I tried doing a pointer to a instance that can take a list but now I’m getting a new error..
class ListPOINTER(object):
'''Just like a POINTER but accept a list of ctype as an argument'''
def __init__(self, etype):
self.etype = etype
def from_param(self, param):
if isinstance(param, (list,tuple)):
return (self.etype * len(param))(*param)
#void got_packet(u_char *args, const struct pcap_pkthdr *header,
# const u_char *packet)
args=ListPOINTER()
CALLBACK = ctypes.CFUNCTYPE(ctypes.c_void_p,args(ctypes.c_char_p),ctypes.pointer(pkthdr),ctypes.POINTER(ctypes.c_ubyte))
and this is the error
Got Required netmask
Pcap open live worked!
Filter Compiled!
Filter installed!
Traceback (most recent call last):
File "./libpcap.py", line 81, in <module>
args=ListPOINTER()
TypeError: __init__() takes exactly 2 arguments (1 given)
The callback takes an
int, so declare the callback prototype withctypes.c_intand pass one. Note you can pass a plain Python integer and ctypes will take care of marshaling it correctly to the C function. It doesn’t have to be ac_intinstance. Yourc_int_hackis unnecessary.Update
Here’s an excerpt of what I got to work: