我正在通过 ctypes 使用 libpcap 将我的嗅探器从 C 移植到 Python。这是Python代码:
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)
在 Linux 上,它工作得很好,但在 Mac OS X 上,当我使用句柄时,它会遇到段错误。即使句柄的值有时为负,有时为正。我已经尝试将 pcap_create 的返回类型更改为 unsigned int,但这没有帮助,但我认为它在 OS X 下返回错误的类型...
我在两个系统上用 C 语言执行了 printf("size of pcap_t: %zu\n", sizeof(pcap_t *));
来获取 pcap_t 处理程序类型的大小。在 Linux 上它显示为 4,在 OS X 8 上显示为 4。但我不知道如何继续下去......
还是我走错路了?有人有想法吗?
最佳答案
数据类型很重要。
您需要告诉ctypes,pcap_create()
的返回值是一个指针,并且您需要告诉它pcap_can_set_rfmon()
的参数是一个指针.
你通过这样做来做到这一点
# create handler
pcap_create = _pcap.pcap_create
pcap_create.restype = ctypes.c_void_p
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
pcap_can_set_rfmon.argtypes = [ctypes.c_void_p]
print "can rfmon:",pcap_can_set_rfmon(handle)
pcap_create.restype = ctypes.c_void_p
和
pcap_can_set_rfmon.argtypes = [ctypes.c_void_p]
此处需要 行。此代码适用于 32 位和 64 位指针,因此您可以在 32 位和 64 位 Linux 以及 32 位和 64 位 OS X(以及 32 位和 64 位 Solaris)上使用它以及 32 位和 64 位 FreeBSD 以及...,加载库的代码需要进行任何更改 - 大多数 Un*xes 共享库的名称以“.so”结尾,所以如果您不想要在其他 Un*x 上使用 find_library
,Linux 代码可能就足够了)。
关于通过 ctypes 使用 pcap 的 python 段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13275038/